Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/3party
diff options
context:
space:
mode:
authorSergey Yershov <yershov@corp.mail.ru>2015-06-16 16:33:47 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:54:25 +0300
commit7270eb6a811d0c0ad6c944d957f828427d57a9cb (patch)
tree4aba98c9ed25275c70ccac5ca9683fa24ff9872b /3party
parentafc7736751749cf2ea01197035c57e0408efb4c8 (diff)
Update boost geometry from boost-develop
Diffstat (limited to '3party')
-rw-r--r--3party/boost/boost/geometry/algorithms/append.hpp80
-rw-r--r--3party/boost/boost/geometry/algorithms/area.hpp3
-rw-r--r--3party/boost/boost/geometry/algorithms/assign.hpp37
-rw-r--r--3party/boost/boost/geometry/algorithms/buffer.hpp12
-rw-r--r--3party/boost/boost/geometry/algorithms/centroid.hpp198
-rw-r--r--3party/boost/boost/geometry/algorithms/clear.hpp1
-rw-r--r--3party/boost/boost/geometry/algorithms/convert.hpp17
-rw-r--r--3party/boost/boost/geometry/algorithms/convex_hull.hpp40
-rw-r--r--3party/boost/boost/geometry/algorithms/correct.hpp3
-rw-r--r--3party/boost/boost/geometry/algorithms/covered_by.hpp2
-rw-r--r--3party/boost/boost/geometry/algorithms/crosses.hpp18
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/andoyer_inverse.hpp174
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/assign_box_corners.hpp10
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/azimuth.hpp158
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp380
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp45
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp992
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp15
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp186
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_input.hpp98
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp268
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp735
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/centroid/translating_transformer.hpp119
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/check_iterator_range.hpp4
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp145
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp250
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp196
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/comparable_distance/interface.hpp20
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/counting.hpp107
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/course.hpp40
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp22
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/box_box.hpp2
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/implementation.hpp1
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/interface.hpp2
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp104
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp47
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp31
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp286
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp85
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/point_box.hpp15
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp47
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/disjoint/point_point.hpp165
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/backward_compatibility.hpp58
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/box_to_box.hpp4
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/default_strategies.hpp10
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp383
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp464
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/implementation.hpp13
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/interface.hpp20
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/is_comparable.hpp45
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/iterator_selector.hpp70
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp147
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/linear_to_linear.hpp123
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp256
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp239
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/multipoint_to_range.hpp183
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp504
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp160
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp130
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp333
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/segment_to_box.hpp299
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp33
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/distance/single_to_multi.hpp526
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/box.hpp95
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/implementation.hpp104
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/interface.hpp126
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp77
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/linestring.hpp182
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/multilinestring.hpp86
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/multipoint.hpp348
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/point.hpp99
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/range.hpp93
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp242
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/envelope/segment.hpp339
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/equals/collect_vectors.hpp5
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/expand/box.hpp110
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/expand/implementation.hpp27
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/expand/indexed.hpp144
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/expand/interface.hpp128
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/expand/point.hpp273
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/expand/segment.hpp91
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/extreme_points.hpp19
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/flattening.hpp69
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/get_left_turns.hpp197
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/intersection/box_box.hpp54
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/intersection/implementation.hpp22
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/intersection/interface.hpp309
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/intersection/multi.hpp421
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_simple/areal.hpp6
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_simple/debug_print_boundary_points.hpp81
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_simple/failure_policy.hpp53
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_simple/interface.hpp2
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_simple/linear.hpp307
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_simple/multipoint.hpp9
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/box.hpp27
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp18
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp50
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/debug_validity_phase.hpp4
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp25
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp36
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp32
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/interface.hpp99
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp16
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/linear.hpp81
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp174
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/pointlike.hpp28
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/polygon.hpp231
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/ring.hpp98
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/is_valid/segment.hpp16
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/max_interval_gap.hpp278
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/normalize.hpp294
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/not.hpp17
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/occupation_info.hpp44
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/add_rings.hpp2
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp7
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/assign_parents.hpp73
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/check_enrich.hpp4
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp9
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp46
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/copy_segments.hpp69
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp179
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp2
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/follow.hpp18
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp48
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp3
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/get_ring.hpp21
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp122
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp39
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp4
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp203
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp86
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/get_turns.hpp96
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp202
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp97
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/linear_linear.hpp7
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/overlay.hpp145
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp343
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp8
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/ring_properties.hpp19
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp31
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/select_rings.hpp217
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp26
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/traverse.hpp11
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/overlay/turn_info.hpp1
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/partition.hpp588
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp3
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/recalculate.hpp1
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/areal_areal.hpp64
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/boundary_checker.hpp2
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/de9im.hpp439
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/follow_helpers.hpp33
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/implementation.hpp110
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/interface.hpp348
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/less.hpp4
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/linear_areal.hpp423
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/linear_linear.hpp60
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/point_geometry.hpp29
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/point_point.hpp39
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/relate.hpp339
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/relate_impl.hpp80
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/result.hpp671
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relate/turns.hpp152
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relation/implementation.hpp18
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/relation/interface.hpp186
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/ring_identifier.hpp18
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/sections/range_by_section.hpp18
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/sections/section_box_policies.hpp49
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/sections/section_functions.hpp66
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/sections/sectionalize.hpp368
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/signed_index_type.hpp30
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/single_geometry.hpp15
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/sub_range.hpp26
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/sweep.hpp87
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/thomas_inverse.hpp203
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/throw_on_empty_input.hpp21
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/turns/compare_turns.hpp36
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/turns/debug_turn.hpp4
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/turns/print_turns.hpp45
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp2
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/vincenty_direct.hpp190
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/vincenty_inverse.hpp218
-rw-r--r--3party/boost/boost/geometry/algorithms/detail/within/point_in_geometry.hpp32
-rw-r--r--3party/boost/boost/geometry/algorithms/dispatch/distance.hpp35
-rw-r--r--3party/boost/boost/geometry/algorithms/dispatch/envelope.hpp49
-rw-r--r--3party/boost/boost/geometry/algorithms/dispatch/expand.hpp58
-rw-r--r--3party/boost/boost/geometry/algorithms/dispatch/is_valid.hpp6
-rw-r--r--3party/boost/boost/geometry/algorithms/envelope.hpp289
-rw-r--r--3party/boost/boost/geometry/algorithms/equals.hpp28
-rw-r--r--3party/boost/boost/geometry/algorithms/expand.hpp343
-rw-r--r--3party/boost/boost/geometry/algorithms/for_each.hpp56
-rw-r--r--3party/boost/boost/geometry/algorithms/intersection.hpp311
-rw-r--r--3party/boost/boost/geometry/algorithms/intersects.hpp19
-rw-r--r--3party/boost/boost/geometry/algorithms/is_convex.hpp160
-rw-r--r--3party/boost/boost/geometry/algorithms/is_empty.hpp207
-rw-r--r--3party/boost/boost/geometry/algorithms/length.hpp9
-rw-r--r--3party/boost/boost/geometry/algorithms/not_implemented.hpp29
-rw-r--r--3party/boost/boost/geometry/algorithms/num_geometries.hpp67
-rw-r--r--3party/boost/boost/geometry/algorithms/num_interior_rings.hpp80
-rw-r--r--3party/boost/boost/geometry/algorithms/num_points.hpp141
-rw-r--r--3party/boost/boost/geometry/algorithms/num_segments.hpp204
-rw-r--r--3party/boost/boost/geometry/algorithms/overlaps.hpp7
-rw-r--r--3party/boost/boost/geometry/algorithms/perimeter.hpp3
-rw-r--r--3party/boost/boost/geometry/algorithms/point_on_surface.hpp72
-rw-r--r--3party/boost/boost/geometry/algorithms/relate.hpp17
-rw-r--r--3party/boost/boost/geometry/algorithms/relation.hpp17
-rw-r--r--3party/boost/boost/geometry/algorithms/remove_spikes.hpp11
-rw-r--r--3party/boost/boost/geometry/algorithms/reverse.hpp3
-rw-r--r--3party/boost/boost/geometry/algorithms/simplify.hpp13
-rw-r--r--3party/boost/boost/geometry/algorithms/touches.hpp24
-rw-r--r--3party/boost/boost/geometry/algorithms/transform.hpp3
-rw-r--r--3party/boost/boost/geometry/algorithms/union.hpp70
-rw-r--r--3party/boost/boost/geometry/algorithms/validity_failure_type.hpp87
-rw-r--r--3party/boost/boost/geometry/algorithms/within.hpp3
-rw-r--r--3party/boost/boost/geometry/arithmetic/arithmetic.hpp101
-rw-r--r--3party/boost/boost/geometry/core/assert.hpp43
-rw-r--r--3party/boost/boost/geometry/core/closure.hpp7
-rw-r--r--3party/boost/boost/geometry/core/coordinate_dimension.hpp18
-rw-r--r--3party/boost/boost/geometry/core/cs.hpp63
-rw-r--r--3party/boost/boost/geometry/core/exception.hpp38
-rw-r--r--3party/boost/boost/geometry/core/interior_type.hpp2
-rw-r--r--3party/boost/boost/geometry/core/point_order.hpp7
-rw-r--r--3party/boost/boost/geometry/core/radian_access.hpp16
-rw-r--r--3party/boost/boost/geometry/core/radius.hpp250
-rw-r--r--3party/boost/boost/geometry/core/ring_type.hpp17
-rw-r--r--3party/boost/boost/geometry/core/srs.hpp195
-rw-r--r--3party/boost/boost/geometry/core/tags.hpp13
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/algebra.hpp46
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/algorithms/assign.hpp129
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/algorithms/clear.hpp64
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/algorithms/convert.hpp87
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/algorithms/detail.hpp356
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/algorithms/reverse.hpp66
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/algorithms/rotation.hpp268
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/algorithms/transform_geometrically.hpp173
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/algorithms/translation.hpp44
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/core/access.hpp137
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/core/coordinate_dimension.hpp58
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/core/coordinate_system.hpp73
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/core/coordinate_type.hpp73
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/core/tags.hpp33
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/concepts/check.hpp70
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/concepts/matrix_concept.hpp141
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/concepts/quaternion_concept.hpp111
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp141
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp111
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp112
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/matrix.hpp131
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/quaternion.hpp130
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/rotation_matrix.hpp117
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/rotation_quaternion.hpp134
-rw-r--r--3party/boost/boost/geometry/extensions/algebra/geometries/vector.hpp133
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/connect.hpp581
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/detail/overlay/dissolver.hpp656
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/detail/overlay/split_rings.hpp558
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/dissolve.hpp307
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/distance_info.hpp232
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/midpoints.hpp131
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/offset.hpp193
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/offset_appender.hpp96
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/parse.hpp123
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/point_on_line.hpp75
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/remove_holes_if.hpp163
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/remove_marked.hpp224
-rw-r--r--3party/boost/boost/geometry/extensions/algorithms/selected.hpp278
-rw-r--r--3party/boost/boost/geometry/extensions/arithmetic/cross_product.hpp110
-rw-r--r--3party/boost/boost/geometry/extensions/astronomy/core/cs.hpp53
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmath.h2849
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathbig.h6064
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathint.h1922
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathmisc.h250
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathobjects.h809
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathparser.h2777
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmaththreads.h250
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathtypes.h675
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint.h4121
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_noasm.h1017
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86.h1602
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64.h1146
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64_msvc.asm548
-rw-r--r--3party/boost/boost/geometry/extensions/contrib/ttmath_stub.hpp373
-rw-r--r--3party/boost/boost/geometry/extensions/gis/geographic/core/cs.hpp81
-rw-r--r--3party/boost/boost/geometry/extensions/gis/geographic/strategies/area_huiller_earth.hpp64
-rw-r--r--3party/boost/boost/geometry/extensions/gis/geographic/strategies/distance_cross_track.hpp70
-rw-r--r--3party/boost/boost/geometry/extensions/gis/geographic/strategies/dms_parser.hpp278
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/shapelib/dbf_write_attribute.hpp87
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp154
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/shapelib/shape_reader.hpp72
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/shapelib/shp_create_object.hpp232
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/shapelib/shp_create_object_multi.hpp147
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/shapelib/shp_read_object.hpp225
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/veshape/write_veshape.hpp281
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp262
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp176
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp301
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/wkb/detail/writer.hpp234
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/wkb/read_wkb.hpp108
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/wkb/utility.hpp99
-rw-r--r--3party/boost/boost/geometry/extensions/gis/io/wkb/write_wkb.hpp128
-rw-r--r--3party/boost/boost/geometry/extensions/gis/latlong/detail/graticule.hpp238
-rw-r--r--3party/boost/boost/geometry/extensions/gis/latlong/latlong.hpp51
-rw-r--r--3party/boost/boost/geometry/extensions/gis/latlong/point_ll.hpp269
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/epsg.hpp3568
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/epsg_traits.hpp43
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/factory.hpp267
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/aasincos.hpp107
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/adjlon.hpp70
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp100
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/base_static.hpp110
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/factory_entry.hpp43
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/function_overloads.hpp35
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_auth.hpp88
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_datum_set.hpp167
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_datums.hpp106
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_ell_set.hpp157
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_ellps.hpp93
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_fwd.hpp99
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_gauss.hpp130
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_init.hpp301
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_inv.hpp80
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp112
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp54
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_param.hpp155
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp71
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp84
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp53
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_units.hpp75
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/pj_zpoly1.hpp100
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/proj_mdist.hpp138
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/impl/projects.hpp181
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/new_projection.hpp54
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/parameters.hpp65
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/aea.hpp545
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/aeqd.hpp487
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/airy.hpp231
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/aitoff.hpp300
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/august.hpp148
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/bacon.hpp247
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/bipc.hpp268
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/boggs.hpp164
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/bonne.hpp270
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/cass.hpp477
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/cc.hpp157
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/cea.hpp246
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/chamb.hpp257
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/collg.hpp163
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/crast.hpp153
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/denoy.hpp148
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/eck1.hpp149
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/eck2.hpp162
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/eck3.hpp296
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/eck4.hpp177
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/eck5.hpp150
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/eqc.hpp156
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/eqdc.hpp230
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/etmerc.hpp370
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/fahey.hpp150
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/fouc_s.hpp182
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/gall.hpp151
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/geocent.hpp151
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/geos.hpp355
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/gins8.hpp147
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/gn_sinu.hpp398
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/gnom.hpp240
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/goode.hpp169
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/gstmerc.hpp184
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/hammer.hpp162
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/hatano.hpp184
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/healpix.hpp846
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/igh.hpp315
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/imw_p.hpp296
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/isea.hpp1249
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/krovak.hpp342
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/labrd.hpp245
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/laea.hpp414
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/lagrng.hpp172
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/larr.hpp141
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/lask.hpp155
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/latlong.hpp283
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/lcc.hpp267
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/lcca.hpp206
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/loxim.hpp178
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/lsat.hpp312
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/mbt_fps.hpp171
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/mbtfpp.hpp166
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/mbtfpq.hpp181
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/merc.hpp235
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/mill.hpp146
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/mod_ster.hpp491
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/moll.hpp269
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/natearth.hpp205
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/nell.hpp162
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/nell_h.hpp164
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/nocol.hpp170
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/nsper.hpp329
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/nzmg.hpp210
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/ob_tran.hpp355
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/ocea.hpp207
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/oea.hpp196
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/omerc.hpp326
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/ortho.hpp228
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/poly.hpp284
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/putp2.hpp173
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/putp3.hpp206
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/putp4p.hpp211
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/putp5.hpp208
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/putp6.hpp234
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/qsc.hpp502
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/robin.hpp256
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/rouss.hpp223
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/rpoly.hpp168
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/sconics.hpp537
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/somerc.hpp202
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/stere.hpp502
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/sterea.hpp393
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/sts.hpp301
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/tcc.hpp151
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/tcea.hpp158
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/tmerc.hpp504
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/tpeqd.hpp216
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/urm5.hpp162
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/urmfps.hpp214
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/vandg.hpp212
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/vandg2.hpp214
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/vandg4.hpp173
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/wag2.hpp154
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/wag3.hpp160
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/wag7.hpp143
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/wink1.hpp155
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/proj/wink2.hpp170
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/project_inverse_transformer.hpp73
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/project_transformer.hpp65
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/projection.hpp72
-rw-r--r--3party/boost/boost/geometry/extensions/gis/projections/projection_point_type.hpp44
-rw-r--r--3party/boost/boost/geometry/extensions/index/rtree/helpers.hpp68
-rw-r--r--3party/boost/boost/geometry/extensions/index/rtree/rtree.hpp774
-rw-r--r--3party/boost/boost/geometry/extensions/index/rtree/rtree_leaf.hpp253
-rw-r--r--3party/boost/boost/geometry/extensions/index/rtree/rtree_node.hpp493
-rw-r--r--3party/boost/boost/geometry/extensions/iterators/circular_iterator.hpp121
-rw-r--r--3party/boost/boost/geometry/extensions/iterators/section_iterators.hpp233
-rw-r--r--3party/boost/boost/geometry/extensions/iterators/segment_returning_iterator.hpp140
-rw-r--r--3party/boost/boost/geometry/extensions/multi/algorithms/dissolve.hpp99
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/append.hpp45
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/area.hpp83
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/assign.hpp93
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/centroid.hpp61
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/clear.hpp47
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/covered_by.hpp62
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/disjoint.hpp147
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/envelope.hpp71
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/equals.hpp85
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/expand.hpp133
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/num_points.hpp46
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/algorithms/within.hpp232
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/core/access.hpp52
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/core/geometry_id.hpp47
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/core/radius.hpp60
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/core/replace_point_type.hpp47
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/core/tags.hpp32
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/core/topological_dimension.hpp50
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/geometries/concepts/check.hpp50
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp122
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/geometries/nsphere.hpp144
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/bounds.hpp46
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/comparable_distance_near.hpp42
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/content.hpp76
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/is_valid.hpp33
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/margin.hpp59
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/index/detail/indexable.hpp30
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/index/detail/rtree/linear/redistribute_elements.hpp109
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/index/detail/rtree/rstar/redistribute_elements.hpp74
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/index/indexable.hpp25
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/nsphere.hpp57
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/strategies/cartesian/nsphere_in_box.hpp175
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/strategies/cartesian/point_in_nsphere.hpp147
-rw-r--r--3party/boost/boost/geometry/extensions/nsphere/views/center_view.hpp105
-rw-r--r--3party/boost/boost/geometry/extensions/strategies/cartesian/distance_info.hpp180
-rw-r--r--3party/boost/boost/geometry/extensions/strategies/parse.hpp41
-rw-r--r--3party/boost/boost/geometry/extensions/util/get_cs_as_radian.hpp55
-rw-r--r--3party/boost/boost/geometry/extensions/util/replace_point_type.hpp98
-rw-r--r--3party/boost/boost/geometry/extensions/views/enveloped_view.hpp126
-rw-r--r--3party/boost/boost/geometry/extensions/views/section_view.hpp73
-rw-r--r--3party/boost/boost/geometry/geometries/adapted/boost_fusion.hpp24
-rw-r--r--3party/boost/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp2
-rw-r--r--3party/boost/boost/geometry/geometries/box.hpp89
-rw-r--r--3party/boost/boost/geometry/geometries/concepts/point_concept.hpp30
-rw-r--r--3party/boost/boost/geometry/geometries/helper_geometry.hpp162
-rw-r--r--3party/boost/boost/geometry/geometries/linestring.hpp28
-rw-r--r--3party/boost/boost/geometry/geometries/multi_linestring.hpp39
-rw-r--r--3party/boost/boost/geometry/geometries/multi_point.hpp29
-rw-r--r--3party/boost/boost/geometry/geometries/multi_polygon.hpp40
-rw-r--r--3party/boost/boost/geometry/geometries/point.hpp137
-rw-r--r--3party/boost/boost/geometry/geometries/point_xy.hpp10
-rw-r--r--3party/boost/boost/geometry/geometries/pointing_segment.hpp142
-rw-r--r--3party/boost/boost/geometry/geometries/polygon.hpp48
-rw-r--r--3party/boost/boost/geometry/geometries/ring.hpp28
-rw-r--r--3party/boost/boost/geometry/geometries/segment.hpp21
-rw-r--r--3party/boost/boost/geometry/geometries/variant.hpp7
-rw-r--r--3party/boost/boost/geometry/geometry.hpp23
-rw-r--r--3party/boost/boost/geometry/index/detail/algorithms/content.hpp16
-rw-r--r--3party/boost/boost/geometry/index/detail/algorithms/intersection_content.hpp4
-rw-r--r--3party/boost/boost/geometry/index/detail/algorithms/is_valid.hpp23
-rw-r--r--3party/boost/boost/geometry/index/detail/algorithms/margin.hpp28
-rw-r--r--3party/boost/boost/geometry/index/detail/assert.hpp21
-rw-r--r--3party/boost/boost/geometry/index/detail/bounded_view.hpp4
-rw-r--r--3party/boost/boost/geometry/index/detail/distance_predicates.hpp18
-rw-r--r--3party/boost/boost/geometry/index/detail/exception.hpp33
-rw-r--r--3party/boost/boost/geometry/index/detail/predicates.hpp135
-rw-r--r--3party/boost/boost/geometry/index/detail/pushable_array.hpp171
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/iterators.hpp122
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp45
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/auto_deallocator.hpp38
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp88
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/node.hpp69
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/node_elements.hpp95
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp48
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp (renamed from 3party/boost/boost/geometry/index/detail/rtree/node/node_auto_ptr.hpp)24
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp (renamed from 3party/boost/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp)112
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/variant_static.hpp (renamed from 3party/boost/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp)90
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/variant_visitor.hpp (renamed from 3party/boost/boost/geometry/index/detail/rtree/node/static_visitor.hpp)28
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp (renamed from 3party/boost/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp)196
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/weak_static.hpp (renamed from 3party/boost/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp)79
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/node/weak_visitor.hpp67
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/options.hpp24
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/pack_create.hpp52
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp97
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/query_iterators.hpp294
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp235
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/rstar/insert.hpp37
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp140
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp110
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/visitors/copy.hpp10
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/visitors/count.hpp83
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/visitors/destroy.hpp5
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/visitors/distance_query.hpp56
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/visitors/insert.hpp53
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/visitors/is_leaf.hpp8
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/visitors/iterator.hpp134
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/visitors/remove.hpp50
-rw-r--r--3party/boost/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp14
-rw-r--r--3party/boost/boost/geometry/index/detail/serialization.hpp36
-rw-r--r--3party/boost/boost/geometry/index/detail/varray.hpp74
-rw-r--r--3party/boost/boost/geometry/index/detail/varray_detail.hpp24
-rw-r--r--3party/boost/boost/geometry/index/equal_to.hpp9
-rw-r--r--3party/boost/boost/geometry/index/indexable.hpp6
-rw-r--r--3party/boost/boost/geometry/index/parameters.hpp7
-rw-r--r--3party/boost/boost/geometry/index/predicates.hpp90
-rw-r--r--3party/boost/boost/geometry/index/rtree.hpp621
-rw-r--r--3party/boost/boost/geometry/io/svg/svg_mapper.hpp21
-rw-r--r--3party/boost/boost/geometry/io/wkt/read.hpp115
-rw-r--r--3party/boost/boost/geometry/io/wkt/write.hpp18
-rw-r--r--3party/boost/boost/geometry/iterators/closing_iterator.hpp25
-rw-r--r--3party/boost/boost/geometry/iterators/concatenate_iterator.hpp65
-rw-r--r--3party/boost/boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp66
-rw-r--r--3party/boost/boost/geometry/iterators/detail/point_iterator/iterator_type.hpp136
-rw-r--r--3party/boost/boost/geometry/iterators/detail/point_iterator/value_type.hpp47
-rw-r--r--3party/boost/boost/geometry/iterators/detail/segment_iterator/iterator_type.hpp153
-rw-r--r--3party/boost/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp215
-rw-r--r--3party/boost/boost/geometry/iterators/detail/segment_iterator/value_type.hpp71
-rw-r--r--3party/boost/boost/geometry/iterators/dispatch/segment_iterator.hpp (renamed from 3party/boost/boost/geometry/iterators/dispatch/point_iterator_type.hpp)18
-rw-r--r--3party/boost/boost/geometry/iterators/ever_circling_iterator.hpp9
-rw-r--r--3party/boost/boost/geometry/iterators/flatten_iterator.hpp87
-rw-r--r--3party/boost/boost/geometry/iterators/point_iterator.hpp129
-rw-r--r--3party/boost/boost/geometry/iterators/point_iterator_type.hpp207
-rw-r--r--3party/boost/boost/geometry/iterators/point_reverse_iterator.hpp20
-rw-r--r--3party/boost/boost/geometry/iterators/segment_iterator.hpp353
-rw-r--r--3party/boost/boost/geometry/multi/algorithms/append.hpp83
-rw-r--r--3party/boost/boost/geometry/multi/algorithms/detail/overlay/select_rings.hpp16
-rw-r--r--3party/boost/boost/geometry/multi/algorithms/intersection.hpp403
-rw-r--r--3party/boost/boost/geometry/multi/algorithms/num_interior_rings.hpp45
-rw-r--r--3party/boost/boost/geometry/multi/algorithms/num_points.hpp69
-rw-r--r--3party/boost/boost/geometry/multi/multi.hpp74
-rw-r--r--3party/boost/boost/geometry/policies/is_valid/default_policy.hpp59
-rw-r--r--3party/boost/boost/geometry/policies/is_valid/failing_reason_policy.hpp218
-rw-r--r--3party/boost/boost/geometry/policies/is_valid/failure_type_policy.hpp83
-rw-r--r--3party/boost/boost/geometry/policies/relate/de9im.hpp168
-rw-r--r--3party/boost/boost/geometry/policies/relate/direction.hpp55
-rw-r--r--3party/boost/boost/geometry/policies/relate/intersection_points.hpp41
-rw-r--r--3party/boost/boost/geometry/policies/relate/tupled.hpp17
-rw-r--r--3party/boost/boost/geometry/policies/robustness/get_rescale_policy.hpp75
-rw-r--r--3party/boost/boost/geometry/policies/robustness/segment_ratio.hpp15
-rw-r--r--3party/boost/boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp8
-rw-r--r--3party/boost/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp11
-rw-r--r--3party/boost/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp52
-rw-r--r--3party/boost/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp90
-rw-r--r--3party/boost/boost/geometry/strategies/agnostic/relate.hpp53
-rw-r--r--3party/boost/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp51
-rw-r--r--3party/boost/boost/geometry/strategies/buffer.hpp14
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/buffer_end_round.hpp22
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/buffer_join_miter.hpp6
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/buffer_join_round.hpp53
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp1
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/buffer_point_circle.hpp17
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/buffer_side_straight.hpp50
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/cart_intersect.hpp169
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/centroid_average.hpp18
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp33
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp41
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/distance_comparable_to_regular.hpp107
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/side_by_triangle.hpp179
-rw-r--r--3party/boost/boost/geometry/strategies/cartesian/side_of_intersection.hpp349
-rw-r--r--3party/boost/boost/geometry/strategies/comparable_distance_result.hpp20
-rw-r--r--3party/boost/boost/geometry/strategies/concepts/convex_hull_concept.hpp7
-rw-r--r--3party/boost/boost/geometry/strategies/concepts/distance_concept.hpp66
-rw-r--r--3party/boost/boost/geometry/strategies/distance_comparable_to_regular.hpp53
-rw-r--r--3party/boost/boost/geometry/strategies/distance_result.hpp36
-rw-r--r--3party/boost/boost/geometry/strategies/geographic/distance_andoyer.hpp224
-rw-r--r--3party/boost/boost/geometry/strategies/geographic/distance_thomas.hpp155
-rw-r--r--3party/boost/boost/geometry/strategies/geographic/distance_vincenty.hpp161
-rw-r--r--3party/boost/boost/geometry/strategies/geographic/mapping_ssf.hpp185
-rw-r--r--3party/boost/boost/geometry/strategies/geographic/side_andoyer.hpp55
-rw-r--r--3party/boost/boost/geometry/strategies/geographic/side_detail.hpp137
-rw-r--r--3party/boost/boost/geometry/strategies/geographic/side_thomas.hpp55
-rw-r--r--3party/boost/boost/geometry/strategies/geographic/side_vincenty.hpp55
-rw-r--r--3party/boost/boost/geometry/strategies/intersection_result.hpp141
-rw-r--r--3party/boost/boost/geometry/strategies/spherical/area_huiller.hpp58
-rw-r--r--3party/boost/boost/geometry/strategies/spherical/distance_cross_track.hpp551
-rw-r--r--3party/boost/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp287
-rw-r--r--3party/boost/boost/geometry/strategies/spherical/distance_haversine.hpp2
-rw-r--r--3party/boost/boost/geometry/strategies/spherical/side_by_cross_track.hpp67
-rw-r--r--3party/boost/boost/geometry/strategies/spherical/ssf.hpp109
-rw-r--r--3party/boost/boost/geometry/strategies/strategies.hpp17
-rw-r--r--3party/boost/boost/geometry/strategies/strategy_transform.hpp33
-rw-r--r--3party/boost/boost/geometry/strategies/transform/matrix_transformers.hpp15
-rw-r--r--3party/boost/boost/geometry/util/bare_type.hpp18
-rw-r--r--3party/boost/boost/geometry/util/combine_if.hpp44
-rw-r--r--3party/boost/boost/geometry/util/compress_variant.hpp44
-rw-r--r--3party/boost/boost/geometry/util/condition.hpp44
-rw-r--r--3party/boost/boost/geometry/util/math.hpp362
-rw-r--r--3party/boost/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp160
-rw-r--r--3party/boost/boost/geometry/util/normalize_spheroidal_coordinates.hpp218
-rw-r--r--3party/boost/boost/geometry/util/promote_integral.hpp318
-rw-r--r--3party/boost/boost/geometry/util/range.hpp102
-rw-r--r--3party/boost/boost/geometry/util/select_calculation_type.hpp27
-rw-r--r--3party/boost/boost/geometry/util/select_coordinate_type.hpp26
-rw-r--r--3party/boost/boost/geometry/util/select_most_precise.hpp23
-rw-r--r--3party/boost/boost/geometry/util/transform_variant.hpp17
-rw-r--r--3party/boost/boost/geometry/views/box_view.hpp6
-rw-r--r--3party/boost/boost/geometry/views/detail/indexed_point_view.hpp33
-rw-r--r--3party/boost/boost/geometry/views/detail/normalized_view.hpp1
-rw-r--r--3party/boost/boost/geometry/views/detail/points_view.hpp3
640 files changed, 99577 insertions, 11053 deletions
diff --git a/3party/boost/boost/geometry/algorithms/append.hpp b/3party/boost/boost/geometry/algorithms/append.hpp
index 1dafac04b6..6ffb5f9587 100644
--- a/3party/boost/boost/geometry/algorithms/append.hpp
+++ b/3party/boost/boost/geometry/algorithms/append.hpp
@@ -8,6 +8,7 @@
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -20,6 +21,12 @@
#define BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
+#include <boost/range.hpp>
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/core/access.hpp>
@@ -28,9 +35,7 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/geometries/variant.hpp>
-#include <boost/range.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/variant/apply_visitor.hpp>
+#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -98,7 +103,7 @@ struct point_to_polygon
else if (ring_index < int(num_interior_rings(polygon)))
{
append_point<ring_type, Point>::apply(
- interior_rings(polygon)[ring_index], point);
+ range::at(interior_rings(polygon), ring_index), point);
}
}
};
@@ -120,7 +125,7 @@ struct range_to_polygon
else if (ring_index < int(num_interior_rings(polygon)))
{
append_range<ring_type, Range>::apply(
- interior_rings(polygon)[ring_index], range);
+ range::at(interior_rings(polygon), ring_index), range);
}
}
};
@@ -202,6 +207,71 @@ struct append<Geometry, RangeOrPoint, point_tag>
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace append
+{
+
+template <typename MultiGeometry, typename RangeOrPoint>
+struct append_to_multigeometry
+{
+ static inline void apply(MultiGeometry& multigeometry,
+ RangeOrPoint const& range_or_point,
+ int ring_index, int multi_index)
+ {
+
+ dispatch::append
+ <
+ typename boost::range_value<MultiGeometry>::type,
+ RangeOrPoint
+ >::apply(range::at(multigeometry, multi_index), range_or_point, ring_index);
+ }
+};
+
+}} // namespace detail::append
+#endif // DOXYGEN_NO_DETAIL
+
+#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>
+{};
+
+template <typename MultiGeometry, typename RangeOrPoint>
+struct append_point<multi_linestring_tag, MultiGeometry, RangeOrPoint>
+ : detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
+{};
+
+template <typename MultiGeometry, typename RangeOrPoint>
+struct append_range<multi_linestring_tag, MultiGeometry, RangeOrPoint>
+ : detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
+{};
+
+template <typename MultiGeometry, typename RangeOrPoint>
+struct append_point<multi_polygon_tag, MultiGeometry, RangeOrPoint>
+ : detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
+{};
+
+template <typename MultiGeometry, typename RangeOrPoint>
+struct append_range<multi_polygon_tag, MultiGeometry, RangeOrPoint>
+ : detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
+{};
+
+} // namespace splitted_dispatch
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
namespace resolve_variant {
diff --git a/3party/boost/boost/geometry/algorithms/area.hpp b/3party/boost/boost/geometry/algorithms/area.hpp
index 7377798719..cb1501d8c9 100644
--- a/3party/boost/boost/geometry/algorithms/area.hpp
+++ b/3party/boost/boost/geometry/algorithms/area.hpp
@@ -18,8 +18,9 @@
#include <boost/mpl/if.hpp>
#include <boost/range/functions.hpp>
#include <boost/range/metafunctions.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/closure.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/assign.hpp b/3party/boost/boost/geometry/algorithms/assign.hpp
index 32f095b9ac..2f325448ad 100644
--- a/3party/boost/boost/geometry/algorithms/assign.hpp
+++ b/3party/boost/boost/geometry/algorithms/assign.hpp
@@ -26,6 +26,10 @@
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.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>
@@ -41,8 +45,6 @@
#include <boost/geometry/util/for_each_coordinate.hpp>
-#include <boost/variant/variant_fwd.hpp>
-
namespace boost { namespace geometry
{
@@ -224,28 +226,27 @@ template <typename Geometry1, typename Geometry2>
struct assign
{
static inline void
- apply(
- Geometry1& geometry1,
- const Geometry2& geometry2)
+ apply(Geometry1& geometry1, const Geometry2& geometry2)
{
concept::check<Geometry1>();
concept::check<Geometry2 const>();
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;
-
+ static bool const same_point_order
+ = point_order<Geometry1>::value == point_order<Geometry2>::value;
BOOST_MPL_ASSERT_MSG
(
- same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER
- , (types<Geometry1, Geometry2>)
+ (same_point_order),
+ ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER,
+ (types<Geometry1, Geometry2>)
);
+ static bool const same_closure
+ = closure<Geometry1>::value == closure<Geometry2>::value;
BOOST_MPL_ASSERT_MSG
(
- same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE
- , (types<Geometry1, Geometry2>)
+ (same_closure),
+ ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE,
+ (types<Geometry1, Geometry2>)
);
dispatch::convert<Geometry2, Geometry1>::apply(geometry2, geometry1);
@@ -317,8 +318,8 @@ struct assign<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
};
-template <BOOST_VARIANT_ENUM_PARAMS(typename A), BOOST_VARIANT_ENUM_PARAMS(typename B)>
-struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(A)>, variant<BOOST_VARIANT_ENUM_PARAMS(B)> >
+template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
+struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
{
struct visitor: static_visitor<void>
{
@@ -337,8 +338,8 @@ struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(A)>, variant<BOOST_VARIANT_ENUM_
};
static inline void
- apply(variant<BOOST_VARIANT_ENUM_PARAMS(A)>& geometry1,
- variant<BOOST_VARIANT_ENUM_PARAMS(B)> const& geometry2)
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
{
return apply_visitor(visitor(), geometry1, geometry2);
}
diff --git a/3party/boost/boost/geometry/algorithms/buffer.hpp b/3party/boost/boost/geometry/algorithms/buffer.hpp
index b8b07ad4d9..16db8578d9 100644
--- a/3party/boost/boost/geometry/algorithms/buffer.hpp
+++ b/3party/boost/boost/geometry/algorithms/buffer.hpp
@@ -17,12 +17,16 @@
#include <cstddef>
#include <boost/numeric/conversion/cast.hpp>
-#include <boost/variant/static_visitor.hpp>
+
+#include <boost/range.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -260,6 +264,12 @@ inline void buffer(GeometryIn const& geometry_in,
geometry_out.clear();
+ if (geometry::is_empty(geometry_in))
+ {
+ // Then output geometry is kept empty as well
+ return;
+ }
+
model::box<point_type> box;
envelope(geometry_in, box);
buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
diff --git a/3party/boost/boost/geometry/algorithms/centroid.hpp b/3party/boost/boost/geometry/algorithms/centroid.hpp
index 2d8a737a18..329c2fd675 100644
--- a/3party/boost/boost/geometry/algorithms/centroid.hpp
+++ b/3party/boost/boost/geometry/algorithms/centroid.hpp
@@ -1,9 +1,15 @@
// 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.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -18,10 +24,11 @@
#include <cstddef>
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
-#include <boost/type_traits/remove_reference.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/closure.hpp>
@@ -36,8 +43,10 @@
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/strategies/centroid.hpp>
#include <boost/geometry/strategies/concepts/centroid_concept.hpp>
@@ -47,8 +56,9 @@
#include <boost/geometry/util/for_each_coordinate.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
-#include <boost/geometry/multi/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
+
+#include <boost/geometry/algorithms/detail/centroid/translating_transformer.hpp>
namespace boost { namespace geometry
@@ -109,8 +119,8 @@ template
<
typename Indexed,
typename Point,
- std::size_t Dimension,
- std::size_t DimensionCount
+ std::size_t Dimension = 0,
+ std::size_t DimensionCount = dimension<Indexed>::type::value
>
struct centroid_indexed_calculator
{
@@ -130,8 +140,7 @@ struct centroid_indexed_calculator
centroid_indexed_calculator
<
- Indexed, Point,
- Dimension + 1, DimensionCount
+ Indexed, Point, Dimension + 1
>::apply(indexed, centroid);
}
};
@@ -154,8 +163,7 @@ struct centroid_indexed
{
centroid_indexed_calculator
<
- Indexed, Point,
- 0, dimension<Indexed>::type::value
+ Indexed, Point
>::apply(indexed, centroid);
}
};
@@ -176,8 +184,9 @@ inline bool range_ok(Range const& range, Point& centroid)
{
#if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW)
throw centroid_exception();
-#endif
+#else
return false;
+#endif
}
else // if (n == 1)
{
@@ -185,20 +194,24 @@ inline bool range_ok(Range const& range, Point& centroid)
geometry::convert(*boost::begin(range), centroid);
return false;
}
- return true;
+ //return true; // unreachable
}
-
/*!
- \brief Calculate the centroid of a ring.
+ \brief Calculate the centroid of a Ring or a Linestring.
*/
template <closure_selector Closure>
struct centroid_range_state
{
- template<typename Ring, typename Strategy>
+ template<typename Ring, typename PointTransformer, typename Strategy>
static inline void apply(Ring const& ring,
- Strategy const& strategy, typename Strategy::state_type& state)
+ PointTransformer const& transformer,
+ Strategy const& strategy,
+ typename Strategy::state_type& state)
{
+ boost::ignore_unused(strategy);
+
+ typedef typename geometry::point_type<Ring const>::type point_type;
typedef typename closeable_view<Ring const, Closure>::type view_type;
typedef typename boost::range_iterator<view_type const>::type iterator_type;
@@ -207,11 +220,19 @@ struct centroid_range_state
iterator_type it = boost::begin(view);
iterator_type end = boost::end(view);
- for (iterator_type previous = it++;
- it != end;
- ++previous, ++it)
+ typename PointTransformer::result_type
+ previous_pt = transformer.apply(*it);
+
+ for ( ++it ; it != end ; ++it)
{
- strategy.apply(*previous, *it, state);
+ typename PointTransformer::result_type
+ pt = transformer.apply(*it);
+
+ strategy.apply(static_cast<point_type const&>(previous_pt),
+ static_cast<point_type const&>(pt),
+ state);
+
+ previous_pt = pt;
}
}
};
@@ -220,15 +241,27 @@ template <closure_selector Closure>
struct centroid_range
{
template<typename Range, typename Point, typename Strategy>
- static inline void apply(Range const& range, Point& centroid,
- Strategy const& strategy)
+ static inline bool apply(Range const& range, Point& centroid,
+ Strategy const& strategy)
{
if (range_ok(range, centroid))
{
+ // prepare translation transformer
+ translating_transformer<Range> transformer(*boost::begin(range));
+
typename Strategy::state_type state;
- centroid_range_state<Closure>::apply(range, strategy, state);
- strategy.result(state, centroid);
+ centroid_range_state<Closure>::apply(range, transformer,
+ strategy, state);
+
+ if ( strategy.result(state, centroid) )
+ {
+ // translate the result back
+ transformer.apply_reverse(centroid);
+ return true;
+ }
}
+
+ return false;
}
};
@@ -240,14 +273,16 @@ struct centroid_range
*/
struct centroid_polygon_state
{
- template<typename Polygon, typename Strategy>
+ template<typename Polygon, typename PointTransformer, typename Strategy>
static inline void apply(Polygon const& poly,
- Strategy const& strategy, typename Strategy::state_type& state)
+ PointTransformer const& transformer,
+ Strategy const& strategy,
+ typename Strategy::state_type& state)
{
typedef typename ring_type<Polygon>::type ring_type;
typedef centroid_range_state<geometry::closure<ring_type>::value> per_ring;
- per_ring::apply(exterior_ring(poly), strategy, state);
+ per_ring::apply(exterior_ring(poly), transformer, strategy, state);
typename interior_return_type<Polygon const>::type
rings = interior_rings(poly);
@@ -255,7 +290,7 @@ struct centroid_polygon_state
for (typename detail::interior_iterator<Polygon const>::type
it = boost::begin(rings); it != boost::end(rings); ++it)
{
- per_ring::apply(*it, strategy, state);
+ per_ring::apply(*it, transformer, strategy, state);
}
}
};
@@ -263,15 +298,27 @@ struct centroid_polygon_state
struct centroid_polygon
{
template<typename Polygon, typename Point, typename Strategy>
- static inline void apply(Polygon const& poly, Point& centroid,
- Strategy const& strategy)
+ static inline bool apply(Polygon const& poly, Point& centroid,
+ Strategy const& strategy)
{
if (range_ok(exterior_ring(poly), centroid))
{
+ // prepare translation transformer
+ translating_transformer<Polygon>
+ transformer(*boost::begin(exterior_ring(poly)));
+
typename Strategy::state_type state;
- centroid_polygon_state::apply(poly, strategy, state);
- strategy.result(state, centroid);
+ centroid_polygon_state::apply(poly, transformer, strategy, state);
+
+ if ( strategy.result(state, centroid) )
+ {
+ // translate the result back
+ transformer.apply_reverse(centroid);
+ return true;
+ }
}
+
+ return false;
}
};
@@ -282,11 +329,15 @@ struct centroid_polygon
*/
struct centroid_multi_point_state
{
- template <typename Point, typename Strategy>
+ template <typename Point, typename PointTransformer, typename Strategy>
static inline void apply(Point const& point,
- Strategy const& strategy, typename Strategy::state_type& state)
+ PointTransformer const& transformer,
+ Strategy const& strategy,
+ typename Strategy::state_type& state)
{
- strategy.apply(point, state);
+ boost::ignore_unused(strategy);
+ strategy.apply(static_cast<Point const&>(transformer.apply(point)),
+ state);
}
};
@@ -303,18 +354,22 @@ template <typename Policy>
struct centroid_multi
{
template <typename Multi, typename Point, typename Strategy>
- static inline void apply(Multi const& multi, Point& centroid,
- Strategy const& strategy)
+ static inline bool 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)
+ if (geometry::is_empty(multi))
{
throw centroid_exception();
}
#endif
+ // prepare translation transformer
+ translating_transformer<Multi> transformer(multi);
+
typename Strategy::state_type state;
for (typename boost::range_iterator<Multi const>::type
@@ -322,9 +377,33 @@ struct centroid_multi
it != boost::end(multi);
++it)
{
- Policy::apply(*it, strategy, state);
+ Policy::apply(*it, transformer, strategy, state);
+ }
+
+ if ( strategy.result(state, centroid) )
+ {
+ // translate the result back
+ transformer.apply_reverse(centroid);
+ return true;
+ }
+
+ return false;
+ }
+};
+
+
+template <typename Algorithm>
+struct centroid_linear_areal
+{
+ template <typename Geometry, typename Point, typename Strategy>
+ static inline void apply(Geometry const& geom,
+ Point& centroid,
+ Strategy const& strategy)
+ {
+ if ( ! Algorithm::apply(geom, centroid, strategy) )
+ {
+ geometry::point_on_border(centroid, geom);
}
- Strategy::result(state, centroid);
}
};
@@ -362,32 +441,47 @@ struct centroid<Segment, segment_tag>
template <typename Ring>
struct centroid<Ring, ring_tag>
- : detail::centroid::centroid_range<geometry::closure<Ring>::value>
+ : detail::centroid::centroid_linear_areal
+ <
+ detail::centroid::centroid_range<geometry::closure<Ring>::value>
+ >
{};
template <typename Linestring>
struct centroid<Linestring, linestring_tag>
- : detail::centroid::centroid_range<closed>
+ : detail::centroid::centroid_linear_areal
+ <
+ detail::centroid::centroid_range<closed>
+ >
{};
template <typename Polygon>
struct centroid<Polygon, polygon_tag>
- : detail::centroid::centroid_polygon
+ : detail::centroid::centroid_linear_areal
+ <
+ detail::centroid::centroid_polygon
+ >
{};
template <typename MultiLinestring>
struct centroid<MultiLinestring, multi_linestring_tag>
- : detail::centroid::centroid_multi
+ : detail::centroid::centroid_linear_areal
<
- detail::centroid::centroid_range_state<closed>
+ detail::centroid::centroid_multi
+ <
+ detail::centroid::centroid_range_state<closed>
+ >
>
{};
template <typename MultiPolygon>
struct centroid<MultiPolygon, multi_polygon_tag>
- : detail::centroid::centroid_multi
+ : detail::centroid::centroid_linear_areal
<
- detail::centroid::centroid_polygon_state
+ detail::centroid::centroid_multi
+ <
+ detail::centroid::centroid_polygon_state
+ >
>
{};
diff --git a/3party/boost/boost/geometry/algorithms/clear.hpp b/3party/boost/boost/geometry/algorithms/clear.hpp
index 1850816b1b..22b61e7c30 100644
--- a/3party/boost/boost/geometry/algorithms/clear.hpp
+++ b/3party/boost/boost/geometry/algorithms/clear.hpp
@@ -16,6 +16,7 @@
#include <boost/type_traits/remove_const.hpp>
+
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/convert.hpp b/3party/boost/boost/geometry/algorithms/convert.hpp
index f8685af2d7..5d68854a45 100644
--- a/3party/boost/boost/geometry/algorithms/convert.hpp
+++ b/3party/boost/boost/geometry/algorithms/convert.hpp
@@ -22,8 +22,9 @@
#include <boost/range.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/remove_reference.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
@@ -41,6 +42,8 @@
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
+#include <boost/geometry/util/range.hpp>
+
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/point_order.hpp>
@@ -111,7 +114,7 @@ struct box_to_range
assign_box_corners_oriented<Reverse>(box, range);
if (Close)
{
- range[4] = range[0];
+ range::at(range, 4) = range::at(range, 0);
}
}
};
@@ -160,13 +163,17 @@ struct range_to_range
// point for open output.
view_type view(rview);
- int n = boost::size(view);
+ typedef typename boost::range_size<Range1>::type size_type;
+ size_type n = boost::size(view);
if (geometry::closure<Range2>::value == geometry::open)
{
n--;
}
- int i = 0;
+ // If size == 0 && geometry::open <=> n = numeric_limits<size_type>::max()
+ // but ok, sice below it == end()
+
+ size_type i = 0;
for (typename boost::range_iterator<view_type const>::type it
= boost::begin(view);
it != boost::end(view) && i < n;
@@ -270,7 +277,7 @@ template
bool UseAssignment = boost::is_same<Geometry1, Geometry2>::value
&& !boost::is_array<Geometry1>::value
>
-struct convert: not_implemented<Tag1, Tag2, mpl::int_<DimensionCount> >
+struct convert: not_implemented<Tag1, Tag2, boost::mpl::int_<DimensionCount> >
{};
diff --git a/3party/boost/boost/geometry/algorithms/convex_hull.hpp b/3party/boost/boost/geometry/algorithms/convex_hull.hpp
index d5bd4d92a5..9d07387002 100644
--- a/3party/boost/boost/geometry/algorithms/convex_hull.hpp
+++ b/3party/boost/boost/geometry/algorithms/convex_hull.hpp
@@ -1,8 +1,14 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,12 +21,14 @@
#define BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP
#include <boost/array.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -29,9 +37,11 @@
#include <boost/geometry/strategies/concepts/convex_hull_concept.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/util/condition.hpp>
+
#include <boost/geometry/views/detail/range_type.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/detail/as_range.hpp>
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
@@ -44,7 +54,7 @@ namespace boost { namespace geometry
namespace detail { namespace convex_hull
{
-template <order_selector Order>
+template <order_selector Order, closure_selector Closure>
struct hull_insert
{
@@ -57,7 +67,7 @@ struct hull_insert
typename Strategy::state_type state;
strategy.apply(geometry, state);
- strategy.result(state, out, Order == clockwise);
+ strategy.result(state, out, Order == clockwise, Closure != open);
return out;
}
};
@@ -70,7 +80,8 @@ struct hull_to_geometry
{
hull_insert
<
- geometry::point_order<OutputGeometry>::value
+ geometry::point_order<OutputGeometry>::value,
+ geometry::closure<OutputGeometry>::value
>::apply(geometry,
std::back_inserter(
// Handle linestring, ring and polygon the same:
@@ -115,7 +126,7 @@ struct convex_hull<Box, box_tag>
boost::array<typename point_type<Box>::type, 4> range;
geometry::detail::assign_box_corners_oriented<Reverse>(box, range);
geometry::append(out, range);
- if (Close)
+ if (BOOST_GEOMETRY_CONDITION(Close))
{
geometry::append(out, *boost::begin(range));
}
@@ -124,9 +135,9 @@ struct convex_hull<Box, box_tag>
-template <order_selector Order>
+template <order_selector Order, closure_selector Closure>
struct convex_hull_insert
- : detail::convex_hull::hull_insert<Order>
+ : detail::convex_hull::hull_insert<Order, Closure>
{};
@@ -171,7 +182,8 @@ struct convex_hull_insert
BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
return dispatch::convex_hull_insert<
- geometry::point_order<Geometry>::value
+ geometry::point_order<Geometry>::value,
+ geometry::closure<Geometry>::value
>::apply(geometry, out, strategy);
}
@@ -189,7 +201,7 @@ struct convex_hull_insert
}
};
-}; // namespace resolve_strategy
+} // namespace resolve_strategy
namespace resolve_variant {
@@ -290,7 +302,7 @@ template<typename Geometry, typename OutputGeometry, typename Strategy>
inline void convex_hull(Geometry const& geometry,
OutputGeometry& out, Strategy const& strategy)
{
- if (geometry::num_points(geometry) == 0)
+ if (geometry::is_empty(geometry))
{
// Leave output empty
return;
diff --git a/3party/boost/boost/geometry/algorithms/correct.hpp b/3party/boost/boost/geometry/algorithms/correct.hpp
index 3c61b2c0d2..11ed6ecff9 100644
--- a/3party/boost/boost/geometry/algorithms/correct.hpp
+++ b/3party/boost/boost/geometry/algorithms/correct.hpp
@@ -23,8 +23,9 @@
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/remove_reference.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/covered_by.hpp b/3party/boost/boost/geometry/algorithms/covered_by.hpp
index e50dc338af..eb8e732409 100644
--- a/3party/boost/boost/geometry/algorithms/covered_by.hpp
+++ b/3party/boost/boost/geometry/algorithms/covered_by.hpp
@@ -22,8 +22,8 @@
#include <cstddef>
-#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/crosses.hpp b/3party/boost/boost/geometry/algorithms/crosses.hpp
index 91ed3e0806..7c80700020 100644
--- a/3party/boost/boost/geometry/algorithms/crosses.hpp
+++ b/3party/boost/boost/geometry/algorithms/crosses.hpp
@@ -21,13 +21,17 @@
#define BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP
#include <cstddef>
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
namespace boost { namespace geometry
{
@@ -45,9 +49,9 @@ template
typename Tag2 = typename tag<Geometry2>::type
>
struct crosses
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_crosses_type,
+ detail::de9im::static_mask_crosses_type,
Geometry1,
Geometry2
>
@@ -141,8 +145,8 @@ namespace resolve_variant
};
- template <BOOST_VARIANT_ENUM_PARAMS(typename A), BOOST_VARIANT_ENUM_PARAMS(typename B)>
- struct crosses<variant<BOOST_VARIANT_ENUM_PARAMS(A)>, variant<BOOST_VARIANT_ENUM_PARAMS(B)> >
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
+ struct crosses<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
{
struct visitor: static_visitor<bool>
{
@@ -162,8 +166,8 @@ namespace resolve_variant
static inline bool
apply(
- const variant<BOOST_VARIANT_ENUM_PARAMS(A)>& geometry1,
- const variant<BOOST_VARIANT_ENUM_PARAMS(B)>& geometry2)
+ const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
+ const variant<BOOST_VARIANT_ENUM_PARAMS(T2)>& geometry2)
{
return apply_visitor(visitor(), geometry1, geometry2);
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/andoyer_inverse.hpp b/3party/boost/boost/geometry/algorithms/detail/andoyer_inverse.hpp
new file mode 100644
index 0000000000..c806aeec1a
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/andoyer_inverse.hpp
@@ -0,0 +1,174 @@
+// Boost.Geometry
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ANDOYER_INVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ANDOYER_INVERSE_HPP
+
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+
+
+namespace boost { namespace geometry { namespace detail
+{
+
+/*!
+\brief The solution of the inverse problem of geodesics on latlong coordinates,
+ Forsyth-Andoyer-Lambert type approximation with first order terms.
+\author See
+ - Technical Report: PAUL D. THOMAS, MATHEMATICAL MODELS FOR NAVIGATION SYSTEMS, 1965
+ http://www.dtic.mil/docs/citations/AD0627893
+ - Technical Report: PAUL D. THOMAS, SPHEROIDAL GEODESICS, REFERENCE SYSTEMS, AND LOCAL GEOMETRY, 1970
+ http://www.dtic.mil/docs/citations/AD703541
+*/
+template <typename CT>
+class andoyer_inverse
+{
+public:
+ template <typename T1, typename T2, typename Spheroid>
+ andoyer_inverse(T1 const& lon1,
+ T1 const& lat1,
+ T2 const& lon2,
+ T2 const& lat2,
+ Spheroid const& spheroid)
+ : m_a(get_radius<0>(spheroid))
+ , m_b(get_radius<2>(spheroid))
+ , m_f(detail::flattening<CT>(spheroid))
+ , m_is_result_zero(false)
+ {
+ // coordinates in radians
+
+ if ( math::equals(lon1, lon2)
+ && math::equals(lat1, lat2) )
+ {
+ m_is_result_zero = true;
+ return;
+ }
+
+ CT const pi_half = math::pi<CT>() / CT(2);
+
+ if ( math::equals(math::abs(lat1), pi_half)
+ && math::equals(math::abs(lat2), pi_half) )
+ {
+ m_is_result_zero = true;
+ return;
+ }
+
+ CT const dlon = lon2 - lon1;
+ m_sin_dlon = sin(dlon);
+ m_cos_dlon = cos(dlon);
+ m_sin_lat1 = sin(lat1);
+ m_cos_lat1 = cos(lat1);
+ m_sin_lat2 = sin(lat2);
+ m_cos_lat2 = cos(lat2);
+
+ // H,G,T = infinity if cos_d = 1 or cos_d = -1
+ // lat1 == +-90 && lat2 == +-90
+ // lat1 == lat2 && lon1 == lon2
+ m_cos_d = m_sin_lat1*m_sin_lat2 + m_cos_lat1*m_cos_lat2*m_cos_dlon;
+ m_d = acos(m_cos_d);
+ m_sin_d = sin(m_d);
+
+ // just in case since above lat1 and lat2 is checked
+ // the check below is equal to cos_d == 1 || cos_d == -1 || d == 0
+ if ( math::equals(m_sin_d, CT(0)) )
+ {
+ m_is_result_zero = true;
+ return;
+ }
+ }
+
+ inline CT distance() const
+ {
+ if ( m_is_result_zero )
+ {
+ // TODO return some approximated value
+ return CT(0);
+ }
+
+ CT const K = math::sqr(m_sin_lat1-m_sin_lat2);
+ CT const L = math::sqr(m_sin_lat1+m_sin_lat2);
+ CT const three_sin_d = CT(3) * m_sin_d;
+ // H or G = infinity if cos_d = 1 or cos_d = -1
+ CT const H = (m_d+three_sin_d)/(CT(1)-m_cos_d);
+ CT const G = (m_d-three_sin_d)/(CT(1)+m_cos_d);
+
+ // for e.g. lat1=-90 && lat2=90 here we have G*L=INF*0
+ CT const dd = -(m_f/CT(4))*(H*K+G*L);
+
+ return m_a * (m_d + dd);
+ }
+
+ inline CT azimuth() const
+ {
+ // it's a situation when the endpoints are on the poles +-90 deg
+ // in this case the azimuth could either be 0 or +-pi
+ if ( m_is_result_zero )
+ {
+ return CT(0);
+ }
+
+ CT A = CT(0);
+ CT U = CT(0);
+ if ( ! math::equals(m_cos_lat2, CT(0)) )
+ {
+ CT const tan_lat2 = m_sin_lat2/m_cos_lat2;
+ CT const M = m_cos_lat1*tan_lat2-m_sin_lat1*m_cos_dlon;
+ A = atan2(m_sin_dlon, M);
+ CT const sin_2A = sin(CT(2)*A);
+ U = (m_f/CT(2))*math::sqr(m_cos_lat1)*sin_2A;
+ }
+
+ CT V = CT(0);
+ if ( ! math::equals(m_cos_lat1, CT(0)) )
+ {
+ CT const tan_lat1 = m_sin_lat1/m_cos_lat1;
+ CT const N = m_cos_lat2*tan_lat1-m_sin_lat2*m_cos_dlon;
+ CT const B = atan2(m_sin_dlon, N);
+ CT const sin_2B = sin(CT(2)*B);
+ V = (m_f/CT(2))*math::sqr(m_cos_lat2)*sin_2B;
+ }
+
+ // infinity if sin_d = 0, so cos_d = 1 or cos_d = -1
+ CT const T = m_d / m_sin_d;
+ CT const dA = V*T-U;
+
+ return A - dA;
+ }
+
+private:
+ CT const m_a;
+ CT const m_b;
+ CT const m_f;
+
+ CT m_sin_dlon;
+ CT m_cos_dlon;
+ CT m_sin_lat1;
+ CT m_cos_lat1;
+ CT m_sin_lat2;
+ CT m_cos_lat2;
+
+ CT m_cos_d;
+ CT m_d;
+ CT m_sin_d;
+
+ bool m_is_result_zero;
+};
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ANDOYER_INVERSE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/assign_box_corners.hpp b/3party/boost/boost/geometry/algorithms/detail/assign_box_corners.hpp
index f1bc596138..669d6d3655 100644
--- a/3party/boost/boost/geometry/algorithms/detail/assign_box_corners.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/assign_box_corners.hpp
@@ -19,7 +19,7 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/detail/assign_values.hpp>
-
+#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -80,12 +80,16 @@ 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]);
+ assign_box_corners(box,
+ range::at(corners, 0), range::at(corners, 1),
+ range::at(corners, 3), range::at(corners, 2));
}
else
{
// make clockwise ll,ul,ur,lr
- assign_box_corners(box, corners[0], corners[3], corners[1], corners[2]);
+ assign_box_corners(box,
+ range::at(corners, 0), range::at(corners, 3),
+ range::at(corners, 1), range::at(corners, 2));
}
}
#if defined(_MSC_VER)
diff --git a/3party/boost/boost/geometry/algorithms/detail/azimuth.hpp b/3party/boost/boost/geometry/algorithms/detail/azimuth.hpp
new file mode 100644
index 0000000000..3e9c398f7d
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/azimuth.hpp
@@ -0,0 +1,158 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_AZIMUTH_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_AZIMUTH_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/algorithms/detail/vincenty_inverse.hpp>
+
+namespace boost { namespace geometry
+{
+
+// An azimuth is an angle between a vector/segment from origin to a point of
+// interest and a reference vector. Typically north-based azimuth is used.
+// North direction is used as a reference, angle is measured clockwise
+// (North - 0deg, East - 90deg). For consistency in 2d cartesian CS
+// the reference vector is Y axis, angle is measured clockwise.
+// http://en.wikipedia.org/wiki/Azimuth
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace detail_dispatch
+{
+
+template <typename ReturnType, typename Tag>
+struct azimuth
+ : not_implemented<Tag>
+{};
+
+template <typename ReturnType>
+struct azimuth<ReturnType, geographic_tag>
+{
+ template <typename P1, typename P2, typename Spheroid>
+ static inline ReturnType apply(P1 const& p1, P2 const& p2, Spheroid const& spheroid)
+ {
+ return geometry::detail::vincenty_inverse<ReturnType>
+ ( get_as_radian<0>(p1), get_as_radian<1>(p1),
+ get_as_radian<0>(p2), get_as_radian<1>(p2),
+ spheroid ).azimuth();
+ }
+
+ template <typename P1, typename P2>
+ static inline ReturnType apply(P1 const& p1, P2 const& p2)
+ {
+ return apply(p1, p2, srs::spheroid<ReturnType>());
+ }
+};
+
+template <typename ReturnType>
+struct azimuth<ReturnType, spherical_equatorial_tag>
+{
+ template <typename P1, typename P2, typename Sphere>
+ static inline ReturnType apply(P1 const& p1, P2 const& p2, Sphere const& /*unused*/)
+ {
+ // http://williams.best.vwh.net/avform.htm#Crs
+ ReturnType dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
+ ReturnType cos_p2lat = cos(get_as_radian<1>(p2));
+
+ // An optimization which should kick in often for Boxes
+ //if ( math::equals(dlon, ReturnType(0)) )
+ //if ( get<0>(p1) == get<0>(p2) )
+ //{
+ // return - sin(get_as_radian<1>(p1)) * cos_p2lat);
+ //}
+
+ // "An alternative formula, not requiring the pre-computation of d"
+ // In the formula below dlon is used as "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));
+ }
+
+ template <typename P1, typename P2>
+ static inline ReturnType apply(P1 const& p1, P2 const& p2)
+ {
+ return apply(p1, p2, 0); // dummy model
+ }
+};
+
+template <typename ReturnType>
+struct azimuth<ReturnType, spherical_polar_tag>
+ : azimuth<ReturnType, spherical_equatorial_tag>
+{};
+
+template <typename ReturnType>
+struct azimuth<ReturnType, cartesian_tag>
+{
+ template <typename P1, typename P2, typename Plane>
+ static inline ReturnType apply(P1 const& p1, P2 const& p2, Plane const& /*unused*/)
+ {
+ ReturnType x = get<0>(p2) - get<0>(p1);
+ ReturnType y = get<1>(p2) - get<1>(p1);
+
+ // NOTE: azimuth 0 is at Y axis, increasing right
+ // as in spherical/geographic where 0 is at North axis
+ return atan2(x, y);
+ }
+
+ template <typename P1, typename P2>
+ static inline ReturnType apply(P1 const& p1, P2 const& p2)
+ {
+ return apply(p1, p2, 0); // dummy model
+ }
+};
+
+} // detail_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+/// Calculate azimuth between two points.
+/// The result is in radians.
+template <typename ReturnType, typename Point1, typename Point2>
+inline ReturnType azimuth(Point1 const& p1, Point2 const& p2)
+{
+ return detail_dispatch::azimuth
+ <
+ ReturnType,
+ typename geometry::cs_tag<Point1>::type
+ >::apply(p1, p2);
+}
+
+/// Calculate azimuth between two points.
+/// The result is in radians.
+template <typename ReturnType, typename Point1, typename Point2, typename Model>
+inline ReturnType azimuth(Point1 const& p1, Point2 const& p2, Model const& model)
+{
+ return detail_dispatch::azimuth
+ <
+ ReturnType,
+ typename geometry::cs_tag<Point1>::type
+ >::apply(p1, p2, model);
+}
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_AZIMUTH_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/3party/boost/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
index 51b495d9e3..d08c704fa8 100644
--- a/3party/boost/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
@@ -12,13 +12,17 @@
#include <cstddef>
#include <iterator>
-#include <boost/numeric/conversion/cast.hpp>
+#include <boost/core/ignore_unused.hpp>
+#include <boost/numeric/conversion/cast.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/strategies/buffer.hpp>
@@ -27,8 +31,11 @@
#include <boost/geometry/algorithms/detail/buffer/line_line_intersection.hpp>
#include <boost/geometry/algorithms/detail/buffer/parallel_continue.hpp>
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/algorithms/simplify.hpp>
+#include <boost/geometry/views/detail/normalized_view.hpp>
+
#if defined(BOOST_GEOMETRY_BUFFER_SIMPLIFY_WITH_AX)
#include <boost/geometry/strategies/cartesian/distance_projected_point_ax.hpp>
#endif
@@ -87,6 +94,13 @@ inline void simplify_input(Range const& range,
geometry::simplify(range, simplified, max_distance, strategy);
#endif
+
+ if (boost::size(simplified) == 2
+ && geometry::equals(geometry::range::front(simplified),
+ geometry::range::back(simplified)))
+ {
+ traits::resize<Range>::apply(simplified, 1);
+ }
}
@@ -134,15 +148,25 @@ struct buffer_range
intersection_point);
}
+
switch(join)
{
case strategy::buffer::join_continue :
// No join, we get two consecutive sides
- return;
+ break;
case strategy::buffer::join_concave :
- collection.add_piece(strategy::buffer::buffered_concave,
- previous_input, prev_perp2, perp1);
- return;
+ {
+ std::vector<output_point_type> range_out;
+ range_out.push_back(prev_perp2);
+ range_out.push_back(previous_input);
+ collection.add_piece(strategy::buffer::buffered_concave, previous_input, range_out);
+
+ range_out.clear();
+ range_out.push_back(previous_input);
+ range_out.push_back(perp1);
+ collection.add_piece(strategy::buffer::buffered_concave, previous_input, range_out);
+ }
+ break;
case strategy::buffer::join_spike :
{
// For linestrings, only add spike at one side to avoid
@@ -150,22 +174,24 @@ struct buffer_range
std::vector<output_point_type> range_out;
end_strategy.apply(penultimate_input, prev_perp2, previous_input, perp1, side, distance, range_out);
collection.add_endcap(end_strategy, range_out, previous_input);
+ collection.set_current_ring_concave();
}
- return;
+ break;
case strategy::buffer::join_convex :
- break; // All code below handles this
- }
-
- // The corner is convex, we create a join
- // TODO (future) - avoid a separate vector, add the piece directly
- std::vector<output_point_type> range_out;
- if (join_strategy.apply(intersection_point,
- previous_input, prev_perp2, perp1,
- distance.apply(previous_input, input, side),
- range_out))
- {
- collection.add_piece(strategy::buffer::buffered_join,
- previous_input, range_out);
+ {
+ // The corner is convex, we create a join
+ // TODO (future) - avoid a separate vector, add the piece directly
+ std::vector<output_point_type> range_out;
+ if (join_strategy.apply(intersection_point,
+ previous_input, prev_perp2, perp1,
+ distance.apply(previous_input, input, side),
+ range_out))
+ {
+ collection.add_piece(strategy::buffer::buffered_join,
+ previous_input, range_out);
+ }
+ }
+ break;
}
}
@@ -202,7 +228,7 @@ struct buffer_range
typename EndStrategy,
typename RobustPolicy
>
- static inline void iterate(Collection& collection,
+ static inline strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -215,18 +241,13 @@ struct buffer_range
output_point_type& last_p1,
output_point_type& last_p2)
{
+ boost::ignore_unused(side_strategy);
+
typedef typename std::iterator_traits
<
Iterator
>::value_type point_type;
- typedef typename robust_point_type
- <
- point_type,
- RobustPolicy
- >::type robust_point_type;
-
- robust_point_type previous_robust_input;
point_type second_point, penultimate_point, ultimate_point; // last two points from begin/end
/*
@@ -246,56 +267,64 @@ struct buffer_range
* pup: penultimate_point
*/
+ strategy::buffer::result_code result = strategy::buffer::result_no_output;
bool first = true;
Iterator it = begin;
- geometry::recalculate(previous_robust_input, *begin, robust_policy);
-
std::vector<output_point_type> generated_side;
generated_side.reserve(2);
for (Iterator prev = it++; it != end; ++it)
{
- robust_point_type robust_input;
- geometry::recalculate(robust_input, *it, robust_policy);
- // Check on equality - however, if input is simplified, this is highly
- // unlikely (though possible by rescaling)
- if (! detail::equals::equals_point_point(previous_robust_input, robust_input))
+ generated_side.clear();
+ strategy::buffer::result_code error_code
+ = side_strategy.apply(*prev, *it, side,
+ distance_strategy, generated_side);
+
+ if (error_code == strategy::buffer::result_no_output)
+ {
+ // Because input is simplified, this is improbable,
+ // but it can happen for degenerate geometries
+ // Further handling of this side is skipped
+ continue;
+ }
+ else if (error_code == strategy::buffer::result_error_numerical)
{
- generated_side.clear();
- side_strategy.apply(*prev, *it, side,
- distance_strategy, generated_side);
+ return error_code;
+ }
- if (! first)
- {
- add_join(collection,
- penultimate_point,
- *prev, last_p1, last_p2,
- *it, generated_side.front(), generated_side.back(),
- side,
- distance_strategy, join_strategy, end_strategy,
- robust_policy);
- }
+ BOOST_GEOMETRY_ASSERT(! generated_side.empty());
- collection.add_piece(strategy::buffer::buffered_segment,
- *prev, *it, generated_side, first);
+ result = strategy::buffer::result_normal;
- penultimate_point = *prev;
- ultimate_point = *it;
- last_p1 = generated_side.front();
- last_p2 = generated_side.back();
- prev = it;
- if (first)
- {
- first = false;
- second_point = *it;
- first_p1 = generated_side.front();
- first_p2 = generated_side.back();
- }
+ if (! first)
+ {
+ add_join(collection,
+ penultimate_point,
+ *prev, last_p1, last_p2,
+ *it, generated_side.front(), generated_side.back(),
+ side,
+ distance_strategy, join_strategy, end_strategy,
+ robust_policy);
+ }
+
+ collection.add_side_piece(*prev, *it, generated_side, first);
+
+ penultimate_point = *prev;
+ ultimate_point = *it;
+ last_p1 = generated_side.front();
+ last_p2 = generated_side.back();
+ prev = it;
+ if (first)
+ {
+ first = false;
+ second_point = *it;
+ first_p1 = generated_side.front();
+ first_p2 = generated_side.back();
}
- previous_robust_input = robust_input;
}
+ return result;
}
};
@@ -346,6 +375,27 @@ struct visit_pieces_default_policy
{}
};
+template
+<
+ typename OutputPointType,
+ typename Point,
+ typename Collection,
+ typename DistanceStrategy,
+ typename PointStrategy
+>
+inline void buffer_point(Point const& point, Collection& collection,
+ DistanceStrategy const& distance_strategy,
+ PointStrategy const& point_strategy)
+{
+ collection.start_new_ring();
+ std::vector<OutputPointType> range_out;
+ point_strategy.apply(point, distance_strategy, range_out);
+ collection.add_piece(strategy::buffer::buffered_point, range_out, false);
+ collection.set_piece_center(point);
+ collection.finish_ring();
+}
+
+
}} // namespace detail::buffer
#endif // DOXYGEN_NO_DETAIL
@@ -390,13 +440,10 @@ struct buffer_inserter<point_tag, Point, RingOutput>
PointStrategy const& point_strategy,
RobustPolicy const& )
{
- typedef typename point_type<RingOutput>::type output_point_type;
-
- collection.start_new_ring();
- std::vector<output_point_type> range_out;
- point_strategy.apply(point, distance_strategy, range_out);
- collection.add_piece(strategy::buffer::buffered_point, range_out, false);
- collection.finish_ring();
+ detail::buffer::buffer_point
+ <
+ typename point_type<RingOutput>::type
+ >(point, collection, distance_strategy, point_strategy);
}
};
@@ -420,7 +467,7 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
typename EndStrategy,
typename RobustPolicy
>
- static inline void iterate(Collection& collection,
+ static inline strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -433,21 +480,26 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
typedef detail::buffer::buffer_range<RingOutput> buffer_range;
- buffer_range::iterate(collection, begin, end,
+ strategy::buffer::result_code result
+ = buffer_range::iterate(collection, begin, end,
side,
distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1, first_p2, last_p1, last_p2);
// Generate closing join
- buffer_range::add_join(collection,
- *(end - 2),
- *(end - 1), last_p1, last_p2,
- *(begin + 1), first_p1, first_p2,
- side,
- distance_strategy, join_strategy, end_strategy,
- robust_policy);
+ if (result == strategy::buffer::result_normal)
+ {
+ buffer_range::add_join(collection,
+ *(end - 2),
+ *(end - 1), last_p1, last_p2,
+ *(begin + 1), first_p1, first_p2,
+ side,
+ distance_strategy, join_strategy, end_strategy,
+ robust_policy);
+ }
// Buffer is closed automatically by last closing corner
+ return result;
}
template
@@ -466,30 +518,46 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
- PointStrategy const& ,
+ PointStrategy const& point_strategy,
RobustPolicy const& robust_policy)
{
- if (boost::size(ring) > 3)
- {
- RingOutput simplified;
- detail::buffer::simplify_input(ring, distance, simplified);
+ RingInput simplified;
+ detail::buffer::simplify_input(ring, distance, simplified);
+ strategy::buffer::result_code code = strategy::buffer::result_no_output;
+
+ std::size_t n = boost::size(simplified);
+ std::size_t const min_points = core_detail::closure::minimum_ring_size
+ <
+ geometry::closure<RingInput>::value
+ >::value;
+
+ if (n >= min_points)
+ {
+ detail::normalized_view<RingInput const> view(simplified);
if (distance.negative())
{
// Walk backwards (rings will be reversed afterwards)
- // It might be that this will be changed later.
- // TODO: decide this.
- iterate(collection, boost::rbegin(simplified), boost::rend(simplified),
+ code = iterate(collection, boost::rbegin(view), boost::rend(view),
strategy::buffer::buffer_side_right,
distance, side_strategy, join_strategy, end_strategy, robust_policy);
}
else
{
- iterate(collection, boost::begin(simplified), boost::end(simplified),
+ code = iterate(collection, boost::begin(view), boost::end(view),
strategy::buffer::buffer_side_left,
distance, side_strategy, join_strategy, end_strategy, robust_policy);
}
+ }
+ if (code == strategy::buffer::result_no_output && n >= 1)
+ {
+ // Use point_strategy to buffer degenerated ring
+ detail::buffer::buffer_point<output_point_type>
+ (
+ geometry::range::front(simplified),
+ collection, distance, point_strategy
+ );
}
}
};
@@ -506,19 +574,6 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
typedef typename point_type<output_ring_type>::type output_point_type;
typedef typename point_type<Linestring>::type input_point_type;
- template <typename DistanceStrategy, typename SideStrategy>
- static inline output_point_type first_perpendicular_point(
- input_point_type const& p1, input_point_type const& p2,
- DistanceStrategy const& distance_strategy,
- SideStrategy const& side_strategy)
- {
- std::vector<output_point_type> generated_side;
- side_strategy.apply(p1, p2,
- strategy::buffer::buffer_side_right,
- distance_strategy, generated_side);
- return generated_side.front();
- }
-
template
<
typename Collection,
@@ -529,7 +584,7 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
typename EndStrategy,
typename RobustPolicy
>
- static inline void iterate(Collection& collection,
+ static inline strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -546,21 +601,41 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
// other side of the linestring. If it is the second pass (right),
// we have it already from the first phase (left).
// But for the first pass, we have to generate it
- output_point_type reverse_p1
- = side == strategy::buffer::buffer_side_right
- ? first_p1
- : first_perpendicular_point(ultimate_point, penultimate_point, distance_strategy, side_strategy);
+ output_point_type reverse_p1;
+ if (side == strategy::buffer::buffer_side_right)
+ {
+ reverse_p1 = first_p1;
+ }
+ else
+ {
+ std::vector<output_point_type> generated_side;
+ strategy::buffer::result_code code
+ = side_strategy.apply(ultimate_point, penultimate_point,
+ strategy::buffer::buffer_side_right,
+ distance_strategy, generated_side);
+ if (code != strategy::buffer::result_normal)
+ {
+ // No output or numerical error
+ return code;
+ }
+ reverse_p1 = generated_side.front();
+ }
output_point_type first_p2, last_p1, last_p2;
- detail::buffer::buffer_range<output_ring_type>::iterate(collection,
+ strategy::buffer::result_code result
+ = detail::buffer::buffer_range<output_ring_type>::iterate(collection,
begin, end, side,
distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1, first_p2, last_p1, last_p2);
- std::vector<output_point_type> range_out;
- end_strategy.apply(penultimate_point, last_p2, ultimate_point, reverse_p1, side, distance_strategy, range_out);
- collection.add_endcap(end_strategy, range_out, ultimate_point);
+ if (result == strategy::buffer::result_normal)
+ {
+ std::vector<output_point_type> range_out;
+ end_strategy.apply(penultimate_point, last_p2, ultimate_point, reverse_p1, side, distance_strategy, range_out);
+ collection.add_endcap(end_strategy, range_out, ultimate_point);
+ }
+ return result;
}
template
@@ -578,30 +653,42 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
- PointStrategy const& ,
+ PointStrategy const& point_strategy,
RobustPolicy const& robust_policy)
{
- if (boost::size(linestring) > 1)
- {
- Linestring simplified;
- detail::buffer::simplify_input(linestring, distance, simplified);
+ Linestring simplified;
+ detail::buffer::simplify_input(linestring, distance, simplified);
+ strategy::buffer::result_code code = strategy::buffer::result_no_output;
+ std::size_t n = boost::size(simplified);
+ if (n > 1)
+ {
collection.start_new_ring();
output_point_type first_p1;
- iterate(collection, boost::begin(simplified), boost::end(simplified),
+ code = iterate(collection,
+ boost::begin(simplified), boost::end(simplified),
strategy::buffer::buffer_side_left,
distance, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1);
- iterate(collection, boost::rbegin(simplified), boost::rend(simplified),
- strategy::buffer::buffer_side_right,
- distance, side_strategy, join_strategy, end_strategy, robust_policy,
- first_p1);
+ if (code == strategy::buffer::result_normal)
+ {
+ code = iterate(collection,
+ boost::rbegin(simplified), boost::rend(simplified),
+ strategy::buffer::buffer_side_right,
+ distance, side_strategy, join_strategy, end_strategy, robust_policy,
+ first_p1);
+ }
collection.finish_ring();
}
- else
+ if (code == strategy::buffer::result_no_output && n >= 1)
{
// Use point_strategy to buffer degenerated linestring
+ detail::buffer::buffer_point<output_point_type>
+ (
+ geometry::range::front(simplified),
+ collection, distance, point_strategy
+ );
}
}
};
@@ -640,7 +727,8 @@ private:
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
- RobustPolicy const& robust_policy)
+ RobustPolicy const& robust_policy,
+ bool is_interior)
{
for (Iterator it = begin; it != end; ++it)
{
@@ -648,7 +736,7 @@ private:
policy::apply(*it, collection, distance, side_strategy,
join_strategy, end_strategy, point_strategy,
robust_policy);
- collection.finish_ring();
+ collection.finish_ring(is_interior);
}
}
@@ -676,7 +764,7 @@ private:
iterate(boost::begin(interior_rings), boost::end(interior_rings),
collection, distance, side_strategy,
join_strategy, end_strategy, point_strategy,
- robust_policy);
+ robust_policy, true);
}
public:
@@ -705,7 +793,7 @@ public:
distance, side_strategy,
join_strategy, end_strategy, point_strategy,
robust_policy);
- collection.finish_ring();
+ collection.finish_ring(false, geometry::num_interior_rings(polygon) > 0u);
}
apply_interior_rings(interior_rings(polygon),
@@ -769,6 +857,8 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
VisitPiecesPolicy& visit_pieces_policy
)
{
+ boost::ignore_unused(visit_pieces_policy);
+
typedef detail::buffer::buffered_piece_collection
<
typename geometry::ring_type<GeometryOutput>::type,
@@ -777,6 +867,17 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
collection_type collection(robust_policy);
collection_type const& const_collection = collection;
+ bool const areal = boost::is_same
+ <
+ typename tag_cast<typename tag<GeometryInput>::type, areal_tag>::type,
+ areal_tag
+ >::type::value;
+ bool const linear = boost::is_same
+ <
+ typename tag_cast<typename tag<GeometryInput>::type, linear_tag>::type,
+ linear_tag
+ >::type::value;
+
dispatch::buffer_inserter
<
typename tag_cast
@@ -791,7 +892,12 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
end_strategy, point_strategy,
robust_policy);
- collection.get_turns(geometry_input, distance_strategy);
+ collection.get_turns();
+ collection.classify_turns(linear);
+ if (BOOST_GEOMETRY_CONDITION(areal))
+ {
+ collection.check_remaining_points(distance_strategy);
+ }
// Visit the piece collection. This does nothing (by default), but
// optionally a debugging tool can be attached (e.g. console or svg),
@@ -800,20 +906,30 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
visit_pieces_policy.apply(const_collection, 0);
collection.discard_rings();
- collection.discard_turns();
+ collection.block_turns();
collection.enrich();
collection.traverse();
- if (distance_strategy.negative()
- && boost::is_same
- <
- typename tag_cast<typename tag<GeometryInput>::type, areal_tag>::type,
- areal_tag
- >::type::value)
+ // Reverse all offsetted rings / traversed rings if:
+ // - they were generated on the negative side (deflate) of polygons
+ // - the output is counter clockwise
+ // and avoid reversing twice
+ bool reverse = distance_strategy.negative() && areal;
+ if (BOOST_GEOMETRY_CONDITION(
+ geometry::point_order<GeometryOutput>::value == counterclockwise))
+ {
+ reverse = ! reverse;
+ }
+ if (reverse)
{
collection.reverse();
}
+ if (BOOST_GEOMETRY_CONDITION(distance_strategy.negative() && areal))
+ {
+ collection.discard_nonintersecting_deflated_rings();
+ }
+
collection.template assign<GeometryOutput>(out);
// Visit collection again
diff --git a/3party/boost/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp b/3party/boost/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
index c37f32fd70..380fbe67d8 100644
--- a/3party/boost/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
@@ -9,6 +9,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFER_POLICIES_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFER_POLICIES_HPP
+#define BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION
#include <cstddef>
@@ -35,7 +36,7 @@ namespace detail { namespace buffer
enum intersection_location_type
{
- location_ok, inside_buffer, inside_original
+ location_ok, inside_buffer, location_discard
};
class backtrack_for_buffer
@@ -81,8 +82,8 @@ template <typename Point, typename SegmentRatio>
struct buffer_turn_operation
: public detail::overlay::traversal_turn_operation<Point, SegmentRatio>
{
- int piece_index;
- int index_in_robust_ring;
+ signed_size_type piece_index;
+ signed_size_type index_in_robust_ring;
inline buffer_turn_operation()
: piece_index(-1)
@@ -103,7 +104,7 @@ struct buffer_turn_info
typedef Point point_type;
typedef RobustPoint robust_point_type;
- int turn_index; // TODO: this might go if partition can operate on non-const input
+ std::size_t turn_index; // TODO: this might go if partition can operate on non-const input
RobustPoint robust_point;
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
@@ -120,21 +121,43 @@ struct buffer_turn_info
return robust_point;
}
-
intersection_location_type location;
- int count_within;
- int count_on_offsetted;
- int count_on_helper;
- int count_on_occupied;
- int count_on_multi;
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ robust_point_type rob_pi, rob_pj, rob_qi, rob_qj;
+#endif
+
+ std::size_t count_within;
+
+ bool within_original;
+ std::size_t count_on_original_boundary;
+ signed_size_type count_in_original; // increased by +1 for in ext.ring, -1 for int.ring
+
+ std::size_t count_on_offsetted;
+ std::size_t count_on_helper;
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ std::size_t count_within_near_offsetted;
+#endif
+
+ bool remove_on_multi;
+
+ // Obsolete:
+ std::size_t count_on_occupied;
+ std::size_t count_on_multi;
inline buffer_turn_info()
- : turn_index(-1)
+ : turn_index(0)
, location(location_ok)
, count_within(0)
+ , within_original(false)
+ , count_on_original_boundary(0)
+ , count_in_original(0)
, count_on_offsetted(0)
, count_on_helper(0)
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ , count_within_near_offsetted(0)
+#endif
+ , remove_on_multi(false)
, count_on_occupied(0)
, count_on_multi(0)
{}
diff --git a/3party/boost/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/3party/boost/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
index 2015d18368..46a7c0f7ab 100644
--- a/3party/boost/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
@@ -12,14 +12,18 @@
#include <algorithm>
#include <cstddef>
#include <set>
-#include <boost/range.hpp>
+#include <boost/core/ignore_unused.hpp>
+#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/algorithms/comparable_distance.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/is_convex.hpp>
#include <boost/geometry/strategies/buffer.hpp>
@@ -29,8 +33,9 @@
#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
#include <boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp>
#include <boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp>
-#include <boost/geometry/algorithms/detail/buffer/turn_in_input.hpp>
+#include <boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_box.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/enrichment_info.hpp>
@@ -41,6 +46,8 @@
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/occupation_info.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
+#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
+#include <boost/geometry/algorithms/detail/sections/section_box_policies.hpp>
#include <boost/geometry/util/range.hpp>
@@ -61,6 +68,49 @@ enum segment_relation_code
segment_relation_disjoint
};
+/*
+ * Terminology
+ *
+ * Suppose we make a buffer (using blocked corners) of this rectangle:
+ *
+ * +-------+
+ * | |
+ * | rect |
+ * | |
+ * +-------+
+ *
+ * For the sides we get these four buffered side-pieces (marked with s)
+ * and four buffered corner pieces (marked with c)
+ *
+ * c---+---s---+---c
+ * | | piece | | <- see below for details of the middle top-side-piece
+ * +---+-------+---+
+ * | | | |
+ * s | rect | s <- two side pieces left/right of rect
+ * | | | |
+ * +---+-------+---+
+ * | | piece | | <- one side-piece below, and two corner pieces
+ * c---+---s---+---c
+ *
+ * The outer part of the picture above, using all pieces,
+ * form together the offsetted ring (marked with o below)
+ * The 8 pieces are part of the piece collection and use for inside-checks
+ * The inner parts form (using 1 or 2 points per piece, often co-located)
+ * form together the robust_polygons (marked with r below)
+ * The remaining piece-segments are helper-segments (marked with h)
+ *
+ * ooooooooooooooooo
+ * o h h o
+ * ohhhrrrrrrrrrhhho
+ * o r r o
+ * o r r o
+ * o r r o
+ * ohhhrrrrrrrrrhhho
+ * o h h o
+ * ooooooooooooooooo
+ *
+ */
+
template <typename Ring, typename RobustPolicy>
struct buffered_piece_collection
@@ -75,6 +125,15 @@ struct buffered_piece_collection
RobustPolicy
>::type robust_point_type;
+ // Robust ring/polygon type, always clockwise
+ typedef geometry::model::ring<robust_point_type> robust_ring_type;
+ typedef geometry::model::box<robust_point_type> robust_box_type;
+
+ typedef typename default_comparable_distance_result
+ <
+ robust_point_type
+ >::type robust_comparable_radius_type;
+
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<point_type>::type
@@ -108,7 +167,7 @@ struct buffered_piece_collection
struct robust_turn
{
- int turn_index;
+ std::size_t turn_index;
int operation_index;
robust_point_type point;
segment_identifier seg_id;
@@ -117,50 +176,124 @@ struct buffered_piece_collection
struct piece
{
+ typedef robust_ring_type piece_robust_ring_type;
+ typedef geometry::section<robust_box_type, 1> section_type;
+
strategy::buffer::piece_type type;
- int index;
+ signed_size_type index;
- int left_index; // points to previous piece
- int right_index; // points to next piece
+ signed_size_type left_index; // points to previous piece of same ring
+ signed_size_type right_index; // points to next piece of same ring
- // The next two members form together a complete clockwise ring
+ // The next two members (1, 2) form together a complete clockwise ring
// for each piece (with one dupped point)
+ // The complete clockwise ring is also included as a robust ring (3)
// 1: half, part of offsetted_rings
segment_identifier first_seg_id;
- int last_segment_index; // no segment-identifier - it is the same as first_seg_id
- int offsetted_count;
+ signed_size_type last_segment_index; // no segment-identifier - it is the same as first_seg_id
+ signed_size_type offsetted_count; // part in robust_ring which is part of offsetted ring
+
+#if defined(BOOST_GEOMETRY_BUFFER_USE_HELPER_POINTS)
+ // 2: half, not part of offsetted rings - part of robust ring
+ std::vector<point_type> helper_points; // 4 points for side, 3 points for join - 0 points for flat-end
+#endif
- // 2: half, not part (future: might be indexed in one vector too)
- std::vector<point_type> helper_segments; // 3 points for segment, 2 points for join - 0 points for flat-end
+ bool is_convex;
+ bool is_monotonic_increasing[2]; // 0=x, 1=y
+ bool is_monotonic_decreasing[2]; // 0=x, 1=y
+
+ // Monotonic sections of pieces around points
+ std::vector<section_type> sections;
// Robust representations
- std::vector<robust_turn> robust_turns; // Used only in rescale_pieces - we might use a map instead
- geometry::model::ring<robust_point_type> robust_ring;
- geometry::model::box<robust_point_type> robust_envelope;
+ // 3: complete ring
+ robust_ring_type robust_ring;
+
+ robust_box_type robust_envelope;
+ robust_box_type robust_offsetted_envelope;
+
+ std::vector<robust_turn> robust_turns; // Used only in insert_rescaled_piece_turns - we might use a map instead
+
+ robust_point_type robust_center;
+ robust_comparable_radius_type robust_min_comparable_radius;
+ robust_comparable_radius_type robust_max_comparable_radius;
+
+ piece()
+ : type(strategy::buffer::piece_type_unknown)
+ , index(-1)
+ , left_index(-1)
+ , right_index(-1)
+ , last_segment_index(-1)
+ , offsetted_count(-1)
+ , is_convex(false)
+ , robust_min_comparable_radius(0)
+ , robust_max_comparable_radius(0)
+ {
+ is_monotonic_increasing[0] = false;
+ is_monotonic_increasing[1] = false;
+ is_monotonic_decreasing[0] = false;
+ is_monotonic_decreasing[1] = false;
+ }
+ };
+
+ struct robust_original
+ {
+ typedef robust_ring_type original_robust_ring_type;
+ typedef geometry::sections<robust_box_type, 1> sections_type;
+
+ inline robust_original()
+ : m_is_interior(false)
+ , m_has_interiors(true)
+ {}
+
+ inline robust_original(robust_ring_type const& ring,
+ bool is_interior, bool has_interiors)
+ : m_ring(ring)
+ , m_is_interior(is_interior)
+ , m_has_interiors(has_interiors)
+ {
+ geometry::envelope(m_ring, m_box);
+
+ // create monotonic sections in y-dimension
+ typedef boost::mpl::vector_c<std::size_t, 1> dimensions;
+ geometry::sectionalize<false, dimensions>(m_ring,
+ detail::no_rescale_policy(), m_sections);
+ }
+
+ robust_ring_type m_ring;
+ robust_box_type m_box;
+ sections_type m_sections;
+
+ bool m_is_interior;
+ bool m_has_interiors;
};
typedef std::vector<piece> piece_vector_type;
piece_vector_type m_pieces;
turn_vector_type m_turns;
- int m_first_piece_index;
+ signed_size_type m_first_piece_index;
buffered_ring_collection<buffered_ring<Ring> > offsetted_rings; // indexed by multi_index
- std::vector< std::vector < robust_point_type > > robust_offsetted_rings;
+ std::vector<robust_original> robust_originals; // robust representation of the original(s)
+ robust_ring_type current_robust_ring;
buffered_ring_collection<Ring> traversed_rings;
segment_identifier current_segment_id;
+ // Specificly for offsetted rings around points
+ // but also for large joins with many points
+ typedef geometry::sections<robust_box_type, 2> sections_type;
+ sections_type monotonic_sections;
+
+
RobustPolicy const& m_robust_policy;
struct redundant_turn
{
inline bool operator()(buffer_turn_info_type const& turn) const
{
- // Erase discarded turns (location not OK) and the turns
- // only used to detect oppositeness.
- return turn.location != location_ok
- || turn.opposite();
+ return turn.remove_on_multi;
}
};
@@ -219,7 +352,7 @@ struct buffered_piece_collection
it != boost::end(m_turns);
++it)
{
- if (it->count_on_offsetted >= 1)
+ if (it->location == location_ok)
{
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
if (distance > 0 && ! occupation_map.empty())
@@ -231,6 +364,28 @@ struct buffered_piece_collection
}
}
+ // Remove all points with one or more u/u points from the map
+ // (Alternatively, we could NOT do this here and change all u/u
+ // behaviour in overlay. Currently nothing is done: each polygon is
+ // just followed there. We could also always switch polygons there. For
+ // buffer behaviour, where 3 pieces might meet of which 2 (or more) form
+ // a u/u turn, this last option would have been better, probably).
+ for (iterator_type it = boost::begin(m_turns);
+ it != boost::end(m_turns);
+ ++it)
+ {
+ if (it->both(detail::overlay::operation_union))
+ {
+ typename occupation_map_type::iterator mit =
+ occupation_map.find(it->get_robust_point());
+
+ if (mit != occupation_map.end())
+ {
+ occupation_map.erase(mit);
+ }
+ }
+ }
+
// 2: Remove all points from map which has only one
typename occupation_map_type::iterator it = occupation_map.begin();
while (it != occupation_map.end())
@@ -256,10 +411,9 @@ struct buffered_piece_collection
// intersection-point -> outgoing)
// for all (co-located) points still present in the map
- int index = 0;
for (iterator_type it = boost::begin(m_turns);
it != boost::end(m_turns);
- ++it, ++index)
+ ++it)
{
typename occupation_map_type::iterator mit =
occupation_map.find(it->get_robust_point());
@@ -271,7 +425,7 @@ struct buffered_piece_collection
{
add_incoming_and_outgoing_angles(it->get_robust_point(), *it,
m_pieces,
- index, i, it->operations[i].seg_id,
+ i, it->operations[i].seg_id,
info);
}
@@ -298,74 +452,70 @@ struct buffered_piece_collection
}
#endif
- // If, in a cluster, one turn is blocked, block them all
- for (typename occupation_map_type::const_iterator it = occupation_map.begin();
- it != occupation_map.end(); ++it)
- {
- typename buffer_occupation_info::turn_vector_type const& turns = it->second.turns;
- bool blocked = false;
- for (std::size_t i = 0; i < turns.size(); i++)
- {
- if (m_turns[turns[i].turn_index].blocked())
- {
- blocked = true;
- break;
- }
- }
- if (blocked)
- {
- for (std::size_t i = 0; i < turns.size(); i++)
- {
- m_turns[turns[i].turn_index].count_on_occupied++;
- }
- }
- }
-
- // 4: Mark all turns as not selectable as a starting point for traversing
- // rings. They still can be used to continue already started rings.
+ // Get left turns from all clusters
for (typename occupation_map_type::iterator it = occupation_map.begin();
it != occupation_map.end(); ++it)
{
- typename buffer_occupation_info::turn_vector_type const& turns = it->second.turns;
- for (std::size_t i = 0; i < turns.size(); i++)
- {
- m_turns[turns[i].turn_index].selectable_start = false;
- }
+ it->second.get_left_turns(it->first, m_turns);
}
}
- inline void classify_turns()
+ inline void classify_turns(bool linear)
{
for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it)
{
- if ( it->count_within > 0
- || it->count_on_occupied > 0 )
+ if (it->count_within > 0)
+ {
+ it->location = inside_buffer;
+ }
+ if (it->count_on_original_boundary > 0 && ! linear)
{
it->location = inside_buffer;
}
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ if (it->count_within_near_offsetted > 0)
+ {
+ // Within can have in rare cases a rounding issue. We don't discard this
+ // point, so it can be used to continue started rings in traversal. But
+ // will never start a new ring from this type of points.
+ it->selectable_start = false;
+ }
+#endif
}
}
- template <typename Geometry, typename DistanceStrategy>
- inline void check_remaining_points(Geometry const& input_geometry, DistanceStrategy const& distance_strategy)
+ template <typename DistanceStrategy>
+ inline void check_remaining_points(DistanceStrategy const& distance_strategy)
{
- int const factor = distance_strategy.factor();
+ // Check if a turn is inside any of the originals
- // This might use partition too (for multi-polygons)
+ turn_in_original_visitor<turn_vector_type> visitor(m_turns);
+ geometry::partition
+ <
+ robust_box_type,
+ turn_get_box, turn_in_original_ovelaps_box,
+ original_get_box, original_ovelaps_box,
+ include_turn_policy, detail::partition::include_all_policy
+ >::apply(m_turns, robust_originals, visitor);
+
+ bool const deflate = distance_strategy.negative();
for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it)
{
- if (it->location == location_ok)
+ buffer_turn_info_type& turn = *it;
+ if (turn.location == location_ok)
{
- int code = turn_in_input
- <
- typename geometry::tag<Geometry>::type
- >::apply(it->point, input_geometry);
- if (code * factor == 1)
+ if (deflate && turn.count_in_original <= 0)
+ {
+ // For deflate: it is not in original, discard
+ turn.location = location_discard;
+ }
+ else if (! deflate && turn.count_in_original > 0)
{
- it->location = inside_original;
+ // For inflate: it is in original, discard
+ turn.location = location_discard;
}
}
}
@@ -392,58 +542,11 @@ struct buffered_piece_collection
return true;
}
- inline void rescale_piece_rings()
- {
- for (typename piece_vector_type::iterator it = boost::begin(m_pieces);
- it != boost::end(m_pieces);
- ++it)
- {
- piece& pc = *it;
-
- pc.offsetted_count = pc.last_segment_index - pc.first_seg_id.segment_index;
- BOOST_ASSERT(pc.offsetted_count >= 0);
-
- pc.robust_ring.reserve(pc.offsetted_count + pc.helper_segments.size());
-
- // Add rescaled offsetted segments
- {
- buffered_ring<Ring> const& ring = offsetted_rings[pc.first_seg_id.multi_index];
-
- typedef typename boost::range_iterator<const buffered_ring<Ring> >::type it_type;
- for (it_type it = boost::begin(ring) + pc.first_seg_id.segment_index;
- it != boost::begin(ring) + pc.last_segment_index;
- ++it)
- {
- robust_point_type point;
- geometry::recalculate(point, *it, m_robust_policy);
- pc.robust_ring.push_back(point);
- }
- }
-
- // Add rescaled helper-segments
- {
- typedef typename std::vector<point_type>::const_iterator it_type;
- for (it_type it = boost::begin(pc.helper_segments);
- it != boost::end(pc.helper_segments);
- ++it)
- {
- robust_point_type point;
- geometry::recalculate(point, *it, m_robust_policy);
- pc.robust_ring.push_back(point);
- }
- }
-
- // Calculate the envelope
- geometry::detail::envelope::envelope_range::apply(pc.robust_ring,
- pc.robust_envelope);
- }
- }
-
inline void insert_rescaled_piece_turns()
{
// Add rescaled turn points to corresponding pieces
// (after this, each turn occurs twice)
- int index = 0;
+ std::size_t index = 0;
for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it, ++index)
{
@@ -468,19 +571,20 @@ struct buffered_piece_collection
// Take into account for the box (intersection points should fall inside,
// but in theory they can be one off because of rounding
geometry::expand(pc.robust_envelope, it->robust_point);
+ geometry::expand(pc.robust_offsetted_envelope, it->robust_point);
}
}
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
// Insert all rescaled turn-points into these rings, to form a
// reliable integer-based ring. All turns can be compared (inside) to this
// rings to see if they are inside.
- for (typename piece_vector_type::iterator it = boost::begin(m_pieces);
- it != boost::end(m_pieces);
- ++it)
+ for (typename boost::range_iterator<piece_vector_type>::type
+ it = boost::begin(m_pieces); it != boost::end(m_pieces); ++it)
{
piece& pc = *it;
- int piece_segment_index = pc.first_seg_id.segment_index;
+ signed_size_type piece_segment_index = pc.first_seg_id.segment_index;
if (! pc.robust_turns.empty())
{
if (pc.robust_turns.size() > 1u)
@@ -488,17 +592,18 @@ struct buffered_piece_collection
std::sort(pc.robust_turns.begin(), pc.robust_turns.end(), buffer_operation_less());
}
// Walk through them, in reverse to insert at right index
- int index_offset = pc.robust_turns.size() - 1;
- for (typename std::vector<robust_turn>::const_reverse_iterator
- rit = pc.robust_turns.rbegin();
- rit != pc.robust_turns.rend();
+ signed_size_type index_offset = static_cast<signed_size_type>(pc.robust_turns.size()) - 1;
+ for (typename boost::range_reverse_iterator<const std::vector<robust_turn> >::type
+ rit = boost::const_rbegin(pc.robust_turns);
+ rit != boost::const_rend(pc.robust_turns);
++rit, --index_offset)
{
- int const index_in_vector = 1 + rit->seg_id.segment_index - piece_segment_index;
- BOOST_ASSERT
- (
- index_in_vector > 0 && index_in_vector < pc.offsetted_count
- );
+ signed_size_type const index_in_vector = 1 + rit->seg_id.segment_index - piece_segment_index;
+ BOOST_GEOMETRY_ASSERT
+ (
+ index_in_vector > 0
+ && index_in_vector < pc.offsetted_count
+ );
pc.robust_ring.insert(boost::begin(pc.robust_ring) + index_in_vector, rit->point);
pc.offsetted_count++;
@@ -508,31 +613,161 @@ struct buffered_piece_collection
}
}
- BOOST_ASSERT(assert_indices_in_robust_rings());
+ BOOST_GEOMETRY_ASSERT(assert_indices_in_robust_rings());
+#endif
+ }
+
+ template <std::size_t Dimension>
+ static inline void determine_monotonicity(piece& pc,
+ robust_point_type const& current,
+ robust_point_type const& next)
+ {
+ if (geometry::get<Dimension>(current) >= geometry::get<Dimension>(next))
+ {
+ pc.is_monotonic_increasing[Dimension] = false;
+ }
+ if (geometry::get<Dimension>(current) <= geometry::get<Dimension>(next))
+ {
+ pc.is_monotonic_decreasing[Dimension] = false;
+ }
+ }
+
+ static inline void determine_properties(piece& pc)
+ {
+ pc.is_monotonic_increasing[0] = true;
+ pc.is_monotonic_increasing[1] = true;
+ pc.is_monotonic_decreasing[0] = true;
+ pc.is_monotonic_decreasing[1] = true;
+
+ pc.is_convex = geometry::is_convex(pc.robust_ring);
+
+ if (pc.offsetted_count < 2)
+ {
+ return;
+ }
+
+ typename robust_ring_type::const_iterator current = pc.robust_ring.begin();
+ typename robust_ring_type::const_iterator next = current + 1;
+
+ for (signed_size_type i = 1; i < pc.offsetted_count; i++)
+ {
+ determine_monotonicity<0>(pc, *current, *next);
+ determine_monotonicity<1>(pc, *current, *next);
+ current = next;
+ ++next;
+ }
+ }
+
+ void determine_properties()
+ {
+ for (typename piece_vector_type::iterator it = boost::begin(m_pieces);
+ it != boost::end(m_pieces);
+ ++it)
+ {
+ determine_properties(*it);
+ }
+ }
+
+ inline void reverse_negative_robust_rings()
+ {
+ for (typename piece_vector_type::iterator it = boost::begin(m_pieces);
+ it != boost::end(m_pieces);
+ ++it)
+ {
+ piece& pc = *it;
+ if (geometry::area(pc.robust_ring) < 0)
+ {
+ // Rings can be ccw:
+ // - in a concave piece
+ // - in a line-buffer with a negative buffer-distance
+ std::reverse(pc.robust_ring.begin(), pc.robust_ring.end());
+ }
+ }
+ }
+
+ inline void prepare_buffered_point_piece(piece& pc)
+ {
+ // create monotonic sections in y-dimension
+ typedef boost::mpl::vector_c<std::size_t, 1> dimensions;
+ geometry::sectionalize<false, dimensions>(pc.robust_ring,
+ detail::no_rescale_policy(), pc.sections);
+
+ // Determine min/max radius
+ typedef geometry::model::referring_segment<robust_point_type const>
+ robust_segment_type;
+
+ typename robust_ring_type::const_iterator current = pc.robust_ring.begin();
+ typename robust_ring_type::const_iterator next = current + 1;
+
+ for (signed_size_type i = 1; i < pc.offsetted_count; i++)
+ {
+ robust_segment_type s(*current, *next);
+ robust_comparable_radius_type const d
+ = geometry::comparable_distance(pc.robust_center, s);
+
+ if (i == 1 || d < pc.robust_min_comparable_radius)
+ {
+ pc.robust_min_comparable_radius = d;
+ }
+ if (i == 1 || d > pc.robust_max_comparable_radius)
+ {
+ pc.robust_max_comparable_radius = d;
+ }
+
+ current = next;
+ ++next;
+ }
+ }
+
+ inline void prepare_buffered_point_pieces()
+ {
+ for (typename piece_vector_type::iterator it = boost::begin(m_pieces);
+ it != boost::end(m_pieces);
+ ++it)
+ {
+ if (it->type == geometry::strategy::buffer::buffered_point)
+ {
+ prepare_buffered_point_piece(*it);
+ }
+ }
}
- template <typename Geometry, typename DistanceStrategy>
- inline void get_turns(Geometry const& input_geometry, DistanceStrategy const& distance_strategy)
+ inline void get_turns()
{
- rescale_piece_rings();
+ for(typename boost::range_iterator<sections_type>::type it
+ = boost::begin(monotonic_sections);
+ it != boost::end(monotonic_sections);
+ ++it)
+ {
+ enlarge_box(it->bounding_box, 1);
+ }
{
// Calculate the turns
piece_turn_visitor
<
+ piece_vector_type,
buffered_ring_collection<buffered_ring<Ring> >,
turn_vector_type,
RobustPolicy
- > visitor(offsetted_rings, m_turns, m_robust_policy, m_pieces.size());
+ > visitor(m_pieces, offsetted_rings, m_turns, m_robust_policy);
geometry::partition
<
- model::box<robust_point_type>, piece_get_box, piece_ovelaps_box
- >::apply(m_pieces, visitor);
+ robust_box_type,
+ detail::section::get_section_box,
+ detail::section::overlaps_section_box
+ >::apply(monotonic_sections, visitor);
}
insert_rescaled_piece_turns();
+ reverse_negative_robust_rings();
+
+ determine_properties();
+
+ prepare_buffered_point_pieces();
+
{
// Check if it is inside any of the pieces
turn_in_piece_visitor
@@ -542,67 +777,130 @@ struct buffered_piece_collection
geometry::partition
<
- model::box<robust_point_type>,
+ robust_box_type,
turn_get_box, turn_ovelaps_box,
piece_get_box, piece_ovelaps_box
>::apply(m_turns, m_pieces, visitor);
}
-
-
- get_occupation();
-
- classify_turns();
-
- check_remaining_points(input_geometry, distance_strategy);
}
inline void start_new_ring()
{
- int const n = offsetted_rings.size();
+ signed_size_type const n = static_cast<signed_size_type>(offsetted_rings.size());
current_segment_id.source_index = 0;
current_segment_id.multi_index = n;
current_segment_id.ring_index = -1;
current_segment_id.segment_index = 0;
offsetted_rings.resize(n + 1);
+ current_robust_ring.clear();
+
+ m_first_piece_index = static_cast<signed_size_type>(boost::size(m_pieces));
+ }
- m_first_piece_index = boost::size(m_pieces);
+ inline void update_closing_point()
+ {
+ BOOST_GEOMETRY_ASSERT(! offsetted_rings.empty());
+ buffered_ring<Ring>& added = offsetted_rings.back();
+ if (! boost::empty(added))
+ {
+ range::back(added) = range::front(added);
+ }
}
- inline void finish_ring()
+ inline void update_last_point(point_type const& p,
+ buffered_ring<Ring>& ring)
{
- BOOST_ASSERT(m_first_piece_index != -1);
- if (m_first_piece_index < static_cast<int>(boost::size(m_pieces)))
+ // For the first point of a new piece, and there were already
+ // points in the offsetted ring, for some piece types the first point
+ // is a duplicate of the last point of the previous piece.
+
+ // TODO: disable that, that point should not be added
+
+ // For now, it is made equal because due to numerical instability,
+ // it can be a tiny bit off, possibly causing a self-intersection
+
+ BOOST_GEOMETRY_ASSERT(boost::size(m_pieces) > 0);
+ if (! ring.empty()
+ && current_segment_id.segment_index
+ == m_pieces.back().first_seg_id.segment_index)
+ {
+ ring.back() = p;
+ }
+ }
+
+ inline void set_piece_center(point_type const& center)
+ {
+ BOOST_GEOMETRY_ASSERT(! m_pieces.empty());
+ geometry::recalculate(m_pieces.back().robust_center, center,
+ m_robust_policy);
+ }
+
+ inline void finish_ring(bool is_interior = false, bool has_interiors = false)
+ {
+ if (m_first_piece_index == -1)
+ {
+ return;
+ }
+
+ if (m_first_piece_index < static_cast<signed_size_type>(boost::size(m_pieces)))
{
// If piece was added
// Reassign left-of-first and right-of-last
geometry::range::at(m_pieces, m_first_piece_index).left_index
- = boost::size(m_pieces) - 1;
+ = static_cast<signed_size_type>(boost::size(m_pieces)) - 1;
geometry::range::back(m_pieces).right_index = m_first_piece_index;
}
m_first_piece_index = -1;
- }
- inline int add_point(point_type const& p)
- {
- BOOST_ASSERT
+ update_closing_point();
+
+ if (! current_robust_ring.empty())
+ {
+ BOOST_GEOMETRY_ASSERT
(
- boost::size(offsetted_rings) > 0
+ geometry::equals(current_robust_ring.front(),
+ current_robust_ring.back())
);
+ robust_originals.push_back(
+ robust_original(current_robust_ring,
+ is_interior, has_interiors));
+ }
+ }
+
+ inline void set_current_ring_concave()
+ {
+ BOOST_GEOMETRY_ASSERT(boost::size(offsetted_rings) > 0);
+ offsetted_rings.back().has_concave = true;
+ }
+
+ inline signed_size_type add_point(point_type const& p)
+ {
+ BOOST_GEOMETRY_ASSERT(boost::size(offsetted_rings) > 0);
+
+ buffered_ring<Ring>& current_ring = offsetted_rings.back();
+ update_last_point(p, current_ring);
+
current_segment_id.segment_index++;
- offsetted_rings.back().push_back(p);
- return offsetted_rings.back().size();
+ current_ring.push_back(p);
+ return static_cast<signed_size_type>(current_ring.size());
}
//-------------------------------------------------------------------------
- inline piece& add_piece(strategy::buffer::piece_type type, bool decrease_segment_index_by_one)
+ inline piece& create_piece(strategy::buffer::piece_type type,
+ bool decrease_segment_index_by_one)
{
+ if (type == strategy::buffer::buffered_concave)
+ {
+ offsetted_rings.back().has_concave = true;
+ }
+
piece pc;
pc.type = type;
- pc.index = boost::size(m_pieces);
+ pc.index = static_cast<signed_size_type>(boost::size(m_pieces));
pc.first_seg_id = current_segment_id;
// Assign left/right (for first/last piece per ring they will be re-assigned later)
@@ -611,90 +909,237 @@ struct buffered_piece_collection
std::size_t const n = boost::size(offsetted_rings.back());
pc.first_seg_id.segment_index = decrease_segment_index_by_one ? n - 1 : n;
+ pc.last_segment_index = pc.first_seg_id.segment_index;
m_pieces.push_back(pc);
return m_pieces.back();
}
- template <typename Range>
- inline void add_piece(strategy::buffer::piece_type type, point_type const& p1, point_type const& p2,
- Range const& range, bool first)
+ inline void init_rescale_piece(piece& pc, std::size_t helper_points_size)
{
- piece& pc = add_piece(type, ! first);
+ if (pc.first_seg_id.segment_index < 0)
+ {
+ // This indicates an error situation: an earlier piece was empty
+ // It currently does not happen
+ // std::cout << "EMPTY " << pc.type << " " << pc.index << " " << pc.first_seg_id.multi_index << std::endl;
+ pc.offsetted_count = 0;
+ return;
+ }
- // If it follows a non-join (so basically the same piece-type) point b1 should be added.
- // There should be two intersections later and it should be discarded.
- // But for now we need it to calculate intersections
- if (first)
+ BOOST_GEOMETRY_ASSERT(pc.first_seg_id.multi_index >= 0);
+ BOOST_GEOMETRY_ASSERT(pc.last_segment_index >= 0);
+
+ pc.offsetted_count = pc.last_segment_index - pc.first_seg_id.segment_index;
+ BOOST_GEOMETRY_ASSERT(pc.offsetted_count >= 0);
+
+ pc.robust_ring.reserve(pc.offsetted_count + helper_points_size);
+
+ // Add rescaled offsetted segments
+ {
+ buffered_ring<Ring> const& ring = offsetted_rings[pc.first_seg_id.multi_index];
+
+ typedef typename boost::range_iterator<const buffered_ring<Ring> >::type it_type;
+ for (it_type it = boost::begin(ring) + pc.first_seg_id.segment_index;
+ it != boost::begin(ring) + pc.last_segment_index;
+ ++it)
+ {
+ robust_point_type point;
+ geometry::recalculate(point, *it, m_robust_policy);
+ pc.robust_ring.push_back(point);
+ }
+ }
+ }
+
+ inline robust_point_type add_helper_point(piece& pc, const point_type& point)
+ {
+#if defined(BOOST_GEOMETRY_BUFFER_USE_HELPER_POINTS)
+ pc.helper_points.push_back(point);
+#endif
+
+ robust_point_type rob_point;
+ geometry::recalculate(rob_point, point, m_robust_policy);
+ pc.robust_ring.push_back(rob_point);
+ return rob_point;
+ }
+
+ // TODO: this is shared with sectionalize, move to somewhere else (assign?)
+ template <typename Box, typename Value>
+ inline void enlarge_box(Box& box, Value value)
+ {
+ geometry::set<0, 0>(box, geometry::get<0, 0>(box) - value);
+ geometry::set<0, 1>(box, geometry::get<0, 1>(box) - value);
+ geometry::set<1, 0>(box, geometry::get<1, 0>(box) + value);
+ geometry::set<1, 1>(box, geometry::get<1, 1>(box) + value);
+ }
+
+ inline void calculate_robust_envelope(piece& pc)
+ {
+ if (pc.offsetted_count == 0)
+ {
+ return;
+ }
+
+ geometry::detail::envelope::envelope_range<>::apply(pc.robust_ring,
+ pc.robust_envelope);
+
+ geometry::assign_inverse(pc.robust_offsetted_envelope);
+ for (signed_size_type i = 0; i < pc.offsetted_count; i++)
{
- add_point(range.front());
+ geometry::expand(pc.robust_offsetted_envelope, pc.robust_ring[i]);
}
- pc.last_segment_index = add_point(range.back());
- pc.helper_segments.push_back(range.back());
- pc.helper_segments.push_back(p2);
- pc.helper_segments.push_back(p1);
- pc.helper_segments.push_back(range.front());
+ // Take roundings into account, enlarge boxes with 1 integer
+ enlarge_box(pc.robust_envelope, 1);
+ enlarge_box(pc.robust_offsetted_envelope, 1);
+ }
+
+ inline void sectionalize(piece& pc)
+ {
+
+ buffered_ring<Ring> const& ring = offsetted_rings.back();
+
+ typedef geometry::detail::sectionalize::sectionalize_part
+ <
+ point_type,
+ boost::mpl::vector_c<std::size_t, 0, 1> // x,y dimension
+ > sectionalizer;
+
+ // Create a ring-identifier. The source-index is the piece index
+ // The multi_index is as in this collection (the ring), but not used here
+ // The ring_index is not used
+ ring_identifier ring_id(pc.index, pc.first_seg_id.multi_index, -1);
+
+ sectionalizer::apply(monotonic_sections,
+ boost::begin(ring) + pc.first_seg_id.segment_index,
+ boost::begin(ring) + pc.last_segment_index,
+ m_robust_policy,
+ ring_id, 10);
+ }
+
+ inline void finish_piece(piece& pc)
+ {
+ init_rescale_piece(pc, 0u);
+ calculate_robust_envelope(pc);
+ sectionalize(pc);
+ }
+
+ inline void finish_piece(piece& pc,
+ const point_type& point1,
+ const point_type& point2,
+ const point_type& point3)
+ {
+ init_rescale_piece(pc, 3u);
+ if (pc.offsetted_count == 0)
+ {
+ return;
+ }
+
+ add_helper_point(pc, point1);
+ robust_point_type mid_point = add_helper_point(pc, point2);
+ add_helper_point(pc, point3);
+ calculate_robust_envelope(pc);
+ sectionalize(pc);
+
+ current_robust_ring.push_back(mid_point);
+ }
+
+ inline void finish_piece(piece& pc,
+ const point_type& point1,
+ const point_type& point2,
+ const point_type& point3,
+ const point_type& point4)
+ {
+ init_rescale_piece(pc, 4u);
+ add_helper_point(pc, point1);
+ robust_point_type mid_point2 = add_helper_point(pc, point2);
+ robust_point_type mid_point1 = add_helper_point(pc, point3);
+ add_helper_point(pc, point4);
+ sectionalize(pc);
+ calculate_robust_envelope(pc);
+
+ // Add mid-points in other order to current helper_ring
+ current_robust_ring.push_back(mid_point1);
+ current_robust_ring.push_back(mid_point2);
}
inline void add_piece(strategy::buffer::piece_type type, point_type const& p,
point_type const& b1, point_type const& b2)
{
- piece& pc = add_piece(type, false);
+ piece& pc = create_piece(type, false);
add_point(b1);
pc.last_segment_index = add_point(b2);
- pc.helper_segments.push_back(b2);
- pc.helper_segments.push_back(p);
- pc.helper_segments.push_back(b1);
+ finish_piece(pc, b2, p, b1);
}
-
template <typename Range>
- inline piece& add_piece(strategy::buffer::piece_type type, Range const& range, bool decrease_segment_index_by_one)
+ inline void add_range_to_piece(piece& pc, Range const& range, bool add_front)
{
- piece& pc = add_piece(type, decrease_segment_index_by_one);
+ BOOST_GEOMETRY_ASSERT(boost::size(range) != 0u);
- bool first = true;
- int last = offsetted_rings.back().size() + 1;
- for (typename Range::const_iterator it = boost::begin(range);
- it != boost::end(range);
- ++it)
+ typename Range::const_iterator it = boost::begin(range);
+
+ // If it follows a non-join (so basically the same piece-type) point b1 should be added.
+ // There should be two intersections later and it should be discarded.
+ // But for now we need it to calculate intersections
+ if (add_front)
{
- bool add = true;
- if (first)
- {
- // Only for very first one, add first. In all other cases it is shared with previous.
- add = offsetted_rings.back().empty();
- first = false;
- }
- if (add)
- {
- last = add_point(*it);
- }
+ add_point(*it);
+ }
+
+ for (++it; it != boost::end(range); ++it)
+ {
+ pc.last_segment_index = add_point(*it);
+ }
+ }
+
+
+ template <typename Range>
+ inline void add_piece(strategy::buffer::piece_type type, Range const& range,
+ bool decrease_segment_index_by_one)
+ {
+ piece& pc = create_piece(type, decrease_segment_index_by_one);
+ if (boost::size(range) > 0u)
+ {
+ add_range_to_piece(pc, range, offsetted_rings.back().empty());
}
+ finish_piece(pc);
+ }
- pc.last_segment_index = last;
+ template <typename Range>
+ inline void add_side_piece(point_type const& p1, point_type const& p2,
+ Range const& range, bool first)
+ {
+ BOOST_GEOMETRY_ASSERT(boost::size(range) >= 2u);
- return pc;
+ piece& pc = create_piece(strategy::buffer::buffered_segment, ! first);
+ add_range_to_piece(pc, range, first);
+ finish_piece(pc, range.back(), p2, p1, range.front());
}
template <typename Range>
- inline void add_piece(strategy::buffer::piece_type type, point_type const& p, Range const& range)
+ inline void add_piece(strategy::buffer::piece_type type,
+ point_type const& p, Range const& range)
{
- piece& pc = add_piece(type, range, true);
+ piece& pc = create_piece(type, true);
- if (boost::size(range) > 0)
+ if (boost::size(range) > 0u)
{
- pc.helper_segments.push_back(range.back());
- pc.helper_segments.push_back(p);
- pc.helper_segments.push_back(range.front());
+ add_range_to_piece(pc, range, offsetted_rings.back().empty());
+ finish_piece(pc, range.back(), p, range.front());
+ }
+ else
+ {
+ finish_piece(pc);
}
}
template <typename EndcapStrategy, typename Range>
- inline void add_endcap(EndcapStrategy const& strategy, Range const& range, point_type const& end_point)
+ inline void add_endcap(EndcapStrategy const& strategy, Range const& range,
+ point_type const& end_point)
{
+ boost::ignore_unused(strategy);
+
if (range.empty())
{
return;
@@ -747,15 +1192,107 @@ struct buffered_piece_collection
}
}
- inline void discard_turns()
+ inline bool point_coveredby_original(point_type const& point)
{
- m_turns.erase
- (
- std::remove_if(boost::begin(m_turns), boost::end(m_turns),
- redundant_turn()),
- boost::end(m_turns)
- );
+ robust_point_type any_point;
+ geometry::recalculate(any_point, point, m_robust_policy);
+
+ signed_size_type count_in_original = 0;
+
+ // Check of the robust point of this outputted ring is in
+ // any of the robust original rings
+ // This can go quadratic if the input has many rings, and there
+ // are many untouched deflated rings around
+ for (typename std::vector<robust_original>::const_iterator it
+ = robust_originals.begin();
+ it != robust_originals.end();
+ ++it)
+ {
+ robust_original const& original = *it;
+ if (detail::disjoint::disjoint_point_box(any_point,
+ original.m_box))
+ {
+ continue;
+ }
+
+ int const geometry_code
+ = detail::within::point_in_geometry(any_point,
+ original.m_ring);
+
+ if (geometry_code == -1)
+ {
+ // Outside, continue
+ continue;
+ }
+
+ // Apply for possibly nested interior rings
+ if (original.m_is_interior)
+ {
+ count_in_original--;
+ }
+ else if (original.m_has_interiors)
+ {
+ count_in_original++;
+ }
+ else
+ {
+ // Exterior ring without interior rings
+ return true;
+ }
+ }
+ return count_in_original > 0;
+ }
+
+ // For a deflate, all rings around inner rings which are untouched
+ // (no intersections/turns) and which are OUTSIDE the original should
+ // be discarded
+ inline void discard_nonintersecting_deflated_rings()
+ {
+ for(typename buffered_ring_collection<buffered_ring<Ring> >::iterator it
+ = boost::begin(offsetted_rings);
+ it != boost::end(offsetted_rings);
+ ++it)
+ {
+ buffered_ring<Ring>& ring = *it;
+ if (! ring.has_intersections()
+ && boost::size(ring) > 0u
+ && geometry::area(ring) < 0)
+ {
+ if (! point_coveredby_original(geometry::range::front(ring)))
+ {
+ ring.is_untouched_outside_original = true;
+ }
+ }
+ }
+ }
+
+ inline void block_turns()
+ {
+ // To fix left-turn issues like #rt_u13
+ // But currently it causes more other issues than it fixes
+// m_turns.erase
+// (
+// std::remove_if(boost::begin(m_turns), boost::end(m_turns),
+// redundant_turn()),
+// boost::end(m_turns)
+// );
+ for (typename boost::range_iterator<turn_vector_type>::type it =
+ boost::begin(m_turns); it != boost::end(m_turns); ++it)
+ {
+ if (it->location != location_ok)
+ {
+ // Set it to blocked. They should not be discarded, to avoid
+ // generating rings over these turns
+ // Performance goes down a tiny bit from 161 s to 173 because there
+ // are sometimes much more turns.
+ // We might speed it up a bit by keeping only one blocked
+ // intersection per segment, but that is complex to program
+ // because each turn involves two segments
+ it->operations[0].operation = detail::overlay::operation_blocked;
+ it->operations[1].operation = detail::overlay::operation_blocked;
+ }
+ }
}
inline void traverse()
@@ -763,7 +1300,8 @@ struct buffered_piece_collection
typedef detail::overlay::traverse
<
false, false,
- buffered_ring_collection<buffered_ring<Ring> >, buffered_ring_collection<buffered_ring<Ring > >,
+ buffered_ring_collection<buffered_ring<Ring> >,
+ buffered_ring_collection<buffered_ring<Ring > >,
backtrack_for_buffer
> traverser;
@@ -801,16 +1339,24 @@ struct buffered_piece_collection
std::map<ring_identifier, properties> selected;
- // Select all rings which do not have any self-intersection (other ones should be traversed)
- int index = 0;
+ // Select all rings which do not have any self-intersection
+ // Inner rings, for deflate, which do not have intersections, and
+ // which are outside originals, are skipped
+ // (other ones should be traversed)
+ signed_size_type index = 0;
for(typename buffered_ring_collection<buffered_ring<Ring> >::const_iterator it = boost::begin(offsetted_rings);
it != boost::end(offsetted_rings);
++it, ++index)
{
- if (! it->has_intersections())
+ if (! it->has_intersections()
+ && ! it->is_untouched_outside_original)
{
- ring_identifier id(0, index, -1);
- selected[id] = properties(*it, true);
+ properties p = properties(*it);
+ if (p.valid)
+ {
+ ring_identifier id(0, index, -1);
+ selected[id] = p;
+ }
}
}
@@ -821,11 +1367,15 @@ struct buffered_piece_collection
it != boost::end(traversed_rings);
++it, ++index)
{
- ring_identifier id(2, index, -1);
- selected[id] = properties(*it, true);
+ properties p = properties(*it);
+ if (p.valid)
+ {
+ ring_identifier id(2, index, -1);
+ selected[id] = p;
+ }
}
- detail::overlay::assign_parents(offsetted_rings, traversed_rings, selected, false);
+ detail::overlay::assign_parents(offsetted_rings, traversed_rings, selected, true);
return detail::overlay::add_rings<GeometryOutput>(selected, offsetted_rings, traversed_rings, out);
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp b/3party/boost/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp
index 03ec598c90..19c91544ac 100644
--- a/3party/boost/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2012-2015 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
@@ -14,11 +14,14 @@
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/buffer.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
@@ -26,8 +29,6 @@
#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
-#include <boost/geometry/multi/algorithms/within.hpp>
-
namespace boost { namespace geometry
{
@@ -43,12 +44,16 @@ struct buffered_ring_collection_tag : polygonal_tag, multi_tag
template <typename Ring>
struct buffered_ring : public Ring
{
+ bool has_concave;
bool has_accepted_intersections;
bool has_discarded_intersections;
+ bool is_untouched_outside_original;
inline buffered_ring()
- : has_accepted_intersections(false)
+ : has_concave(false)
+ , has_accepted_intersections(false)
, has_discarded_intersections(false)
+ , is_untouched_outside_original(false)
{}
inline bool discarded() const
@@ -221,7 +226,7 @@ struct get_ring<detail::buffer::buffered_ring_collection_tag>
ring_identifier const& id,
MultiGeometry const& multi_ring)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
id.multi_index >= 0
&& id.multi_index < int(boost::size(multi_ring))
diff --git a/3party/boost/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp b/3party/boost/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
index e3c41a2a4b..3425ee6ffd 100644
--- a/3party/boost/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
@@ -16,6 +16,8 @@
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
+#include <boost/geometry/algorithms/detail/sections/section_functions.hpp>
+#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
namespace boost { namespace geometry
@@ -27,36 +29,47 @@ namespace detail { namespace buffer
{
-struct piece_get_box
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+struct buffer_assign_turn
{
- template <typename Box, typename Piece>
- static inline void apply(Box& total, Piece const& piece)
+ 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
+ >
+ static inline void apply(Info& info,
+ Point1 const& /*p1*/,
+ Point2 const& /*p2*/,
+ IntersectionInfo const& iinfo)
{
- geometry::expand(total, piece.robust_envelope);
+ info.rob_pi = iinfo.rpi();
+ info.rob_pj = iinfo.rpj();
+ info.rob_qi = iinfo.rqi();
+ info.rob_qj = iinfo.rqj();
}
-};
-struct piece_ovelaps_box
-{
- template <typename Box, typename Piece>
- static inline bool apply(Box const& box, Piece const& piece)
- {
- return ! geometry::detail::disjoint::disjoint_box_box(box, piece.robust_envelope);
- }
};
+#endif
template
<
+ typename Pieces,
typename Rings,
typename Turns,
typename RobustPolicy
>
class piece_turn_visitor
{
+ Pieces const& m_pieces;
Rings const& m_rings;
Turns& m_turns;
RobustPolicy const& m_robust_policy;
- int m_last_piece_index;
template <typename Piece>
inline bool is_adjacent(Piece const& piece1, Piece const& piece2) const
@@ -66,14 +79,19 @@ class piece_turn_visitor
return false;
}
- if (std::abs(piece1.index - piece2.index) == 1)
+ return piece1.index == piece2.left_index
+ || piece1.index == piece2.right_index;
+ }
+
+ template <typename Piece>
+ inline bool is_on_same_convex_ring(Piece const& piece1, Piece const& piece2) const
+ {
+ if (piece1.first_seg_id.multi_index != piece2.first_seg_id.multi_index)
{
- return true;
+ return false;
}
- return (piece1.index == 0 && piece2.index == m_last_piece_index)
- || (piece1.index == m_last_piece_index && piece2.index == 0)
- ;
+ return ! m_rings[piece1.first_seg_id.multi_index].has_concave;
}
template <typename Range, typename Iterator>
@@ -100,52 +118,112 @@ class piece_turn_visitor
return result;
}
- template <typename Piece>
- inline void calculate_turns(Piece const& piece1, Piece const& piece2)
+ template <std::size_t Dimension, typename Iterator, typename Box>
+ inline void move_begin_iterator(Iterator& it_begin, Iterator it_beyond,
+ signed_size_type& index, int dir, Box const& other_bounding_box)
+ {
+ for(; it_begin != it_beyond
+ && it_begin + 1 != it_beyond
+ && detail::section::preceding<Dimension>(dir, *(it_begin + 1),
+ other_bounding_box, m_robust_policy);
+ ++it_begin, index++)
+ {}
+ }
+
+ template <std::size_t Dimension, typename Iterator, typename Box>
+ inline void move_end_iterator(Iterator it_begin, Iterator& it_beyond,
+ int dir, Box const& other_bounding_box)
+ {
+ while (it_beyond != it_begin
+ && it_beyond - 1 != it_begin
+ && it_beyond - 2 != it_begin)
+ {
+ if (detail::section::exceeding<Dimension>(dir, *(it_beyond - 2),
+ other_bounding_box, m_robust_policy))
+ {
+ --it_beyond;
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+
+ template <typename Piece, typename Section>
+ inline void calculate_turns(Piece const& piece1, Piece const& piece2,
+ Section const& section1, Section const& section2)
{
typedef typename boost::range_value<Rings const>::type ring_type;
typedef typename boost::range_value<Turns const>::type turn_type;
typedef typename boost::range_iterator<ring_type const>::type iterator;
- segment_identifier seg_id1 = piece1.first_seg_id;
- segment_identifier seg_id2 = piece2.first_seg_id;
-
- if (seg_id1.segment_index < 0 || seg_id2.segment_index < 0)
+ signed_size_type const piece1_first_index = piece1.first_seg_id.segment_index;
+ signed_size_type const piece2_first_index = piece2.first_seg_id.segment_index;
+ if (piece1_first_index < 0 || piece2_first_index < 0)
{
return;
}
- ring_type const& ring1 = m_rings[seg_id1.multi_index];
- iterator it1_first = boost::begin(ring1) + seg_id1.segment_index;
- iterator it1_last = boost::begin(ring1) + piece1.last_segment_index;
-
- ring_type const& ring2 = m_rings[seg_id2.multi_index];
- iterator it2_first = boost::begin(ring2) + seg_id2.segment_index;
- iterator it2_last = boost::begin(ring2) + piece2.last_segment_index;
+ // Get indices of part of offsetted_rings for this monotonic section:
+ signed_size_type const sec1_first_index = piece1_first_index + section1.begin_index;
+ signed_size_type const sec2_first_index = piece2_first_index + section2.begin_index;
+
+ // index of last point in section, beyond-end is one further
+ signed_size_type const sec1_last_index = piece1_first_index + section1.end_index;
+ signed_size_type const sec2_last_index = piece2_first_index + section2.end_index;
+
+ // get geometry and iterators over these sections
+ ring_type const& ring1 = m_rings[piece1.first_seg_id.multi_index];
+ iterator it1_first = boost::begin(ring1) + sec1_first_index;
+ iterator it1_beyond = boost::begin(ring1) + sec1_last_index + 1;
+
+ ring_type const& ring2 = m_rings[piece2.first_seg_id.multi_index];
+ iterator it2_first = boost::begin(ring2) + sec2_first_index;
+ iterator it2_beyond = boost::begin(ring2) + sec2_last_index + 1;
+
+ // Set begin/end of monotonic ranges, in both x/y directions
+ signed_size_type index1 = sec1_first_index;
+ move_begin_iterator<0>(it1_first, it1_beyond, index1,
+ section1.directions[0], section2.bounding_box);
+ move_end_iterator<0>(it1_first, it1_beyond,
+ section1.directions[0], section2.bounding_box);
+ move_begin_iterator<1>(it1_first, it1_beyond, index1,
+ section1.directions[1], section2.bounding_box);
+ move_end_iterator<1>(it1_first, it1_beyond,
+ section1.directions[1], section2.bounding_box);
+
+ signed_size_type index2 = sec2_first_index;
+ move_begin_iterator<0>(it2_first, it2_beyond, index2,
+ section2.directions[0], section1.bounding_box);
+ move_end_iterator<0>(it2_first, it2_beyond,
+ section2.directions[0], section1.bounding_box);
+ move_begin_iterator<1>(it2_first, it2_beyond, index2,
+ section2.directions[1], section1.bounding_box);
+ move_end_iterator<1>(it2_first, it2_beyond,
+ section2.directions[1], section1.bounding_box);
turn_type the_model;
the_model.operations[0].piece_index = piece1.index;
the_model.operations[0].seg_id = piece1.first_seg_id;
+ the_model.operations[0].seg_id.segment_index = index1; // override
iterator it1 = it1_first;
for (iterator prev1 = it1++;
- it1 != it1_last;
+ it1 != it1_beyond;
prev1 = it1++, the_model.operations[0].seg_id.segment_index++)
{
the_model.operations[1].piece_index = piece2.index;
the_model.operations[1].seg_id = piece2.first_seg_id;
+ the_model.operations[1].seg_id.segment_index = index2; // override
iterator next1 = next_point(ring1, it1);
iterator it2 = it2_first;
for (iterator prev2 = it2++;
- it2 != it2_last;
+ it2 != it2_beyond;
prev2 = it2++, the_model.operations[1].seg_id.segment_index++)
{
- // Revert (this is used more often - should be common function TODO)
- the_model.operations[0].other_id = the_model.operations[1].seg_id;
- the_model.operations[1].other_id = the_model.operations[0].seg_id;
-
iterator next2 = next_point(ring2, it2);
// TODO: internally get_turn_info calculates robust points.
@@ -155,7 +233,11 @@ class piece_turn_visitor
// and iterating in sync with them...
typedef detail::overlay::get_turn_info
<
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ buffer_assign_turn
+#else
detail::overlay::assign_null_policy
+#endif
> turn_policy;
turn_policy::apply(*prev1, *it1, *next1,
@@ -169,28 +251,36 @@ class piece_turn_visitor
public:
- piece_turn_visitor(Rings const& ring_collection,
+ piece_turn_visitor(Pieces const& pieces,
+ Rings const& ring_collection,
Turns& turns,
- RobustPolicy const& robust_policy,
- int last_piece_index)
- : m_rings(ring_collection)
+ RobustPolicy const& robust_policy)
+ : m_pieces(pieces)
+ , m_rings(ring_collection)
, m_turns(turns)
, m_robust_policy(robust_policy)
- , m_last_piece_index(last_piece_index)
{}
- template <typename Piece>
- inline void apply(Piece const& piece1, Piece const& piece2,
+ template <typename Section>
+ inline void apply(Section const& section1, Section const& section2,
bool first = true)
{
boost::ignore_unused_variable_warning(first);
- if ( is_adjacent(piece1, piece2)
- || detail::disjoint::disjoint_box_box(piece1.robust_envelope,
- piece2.robust_envelope))
+
+ typedef typename boost::range_value<Pieces const>::type piece_type;
+ piece_type const& piece1 = m_pieces[section1.ring_id.source_index];
+ piece_type const& piece2 = m_pieces[section2.ring_id.source_index];
+
+ if ( piece1.index == piece2.index
+ || is_adjacent(piece1, piece2)
+ || is_on_same_convex_ring(piece1, piece2)
+ || detail::disjoint::disjoint_box_box(section1.bounding_box,
+ section2.bounding_box) )
{
return;
}
- calculate_turns(piece1, piece2);
+
+ calculate_turns(piece1, piece2, section1, section2);
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_input.hpp b/3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_input.hpp
deleted file mode 100644
index 2b1c33d291..0000000000
--- a/3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_input.hpp
+++ /dev/null
@@ -1,98 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2012-2014 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_TURN_IN_INPUT_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TURN_IN_INPUT_HPP
-
-#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/algorithms/covered_by.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace buffer
-{
-
-// Checks if an turn/intersection point is inside (or covered by) the input geometry
-
-template <typename Tag>
-struct turn_in_input
-{
-};
-
-template <>
-struct turn_in_input<polygon_tag>
-{
- template <typename Point, typename Geometry>
- static inline int apply(Point const& point, Geometry const& geometry)
- {
- return geometry::covered_by(point, geometry) ? 1 : -1;
- }
-};
-
-template <>
-struct turn_in_input<linestring_tag>
-{
- template <typename Point, typename Geometry>
- static inline int apply(Point const& , Geometry const& )
- {
- return 0;
- }
-};
-
-template <>
-struct turn_in_input<point_tag>
-{
- template <typename Point, typename Geometry>
- static inline int apply(Point const& , Geometry const& )
- {
- return 0;
- }
-};
-
-template <>
-struct turn_in_input<multi_polygon_tag>
-{
- template <typename Point, typename Geometry>
- static inline int apply(Point const& point, Geometry const& geometry)
- {
- return geometry::covered_by(point, geometry) ? 1 : -1;
- }
-};
-
-template <>
-struct turn_in_input<multi_linestring_tag>
-{
- template <typename Point, typename Geometry>
- static inline int apply(Point const& , Geometry const& )
- {
- return 0;
- }
-};
-
-template <>
-struct turn_in_input<multi_point_tag>
-{
- template <typename Point, typename Geometry>
- static inline int apply(Point const& , Geometry const& )
- {
- return 0;
- }
-};
-
-
-}} // namespace detail::buffer
-#endif // DOXYGEN_NO_DETAIL
-
-
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TURN_IN_INPUT_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp b/3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp
new file mode 100644
index 0000000000..05fc6df8ff
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp
@@ -0,0 +1,268 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014 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_TURN_IN_ORIGINAL_VISITOR
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TURN_IN_ORIGINAL_VISITOR
+
+
+#include <boost/core/ignore_unused.hpp>
+
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
+#include <boost/geometry/strategies/buffer.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+struct original_get_box
+{
+ template <typename Box, typename Original>
+ static inline void apply(Box& total, Original const& original)
+ {
+ geometry::expand(total, original.m_box);
+ }
+};
+
+struct original_ovelaps_box
+{
+ template <typename Box, typename Original>
+ static inline bool apply(Box const& box, Original const& original)
+ {
+ return ! detail::disjoint::disjoint_box_box(box, original.m_box);
+ }
+};
+
+struct include_turn_policy
+{
+ template <typename Turn>
+ static inline bool apply(Turn const& turn)
+ {
+ return turn.location == location_ok;
+ }
+};
+
+struct turn_in_original_ovelaps_box
+{
+ template <typename Box, typename Turn>
+ static inline bool apply(Box const& box, Turn const& turn)
+ {
+ if (turn.location != location_ok || turn.within_original)
+ {
+ // Skip all points already processed
+ return false;
+ }
+
+ return ! geometry::detail::disjoint::disjoint_point_box(
+ turn.robust_point, box);
+ }
+};
+
+//! Check if specified is in range of specified iterators
+//! Return value of strategy (true if we can bail out)
+template
+<
+ typename Strategy,
+ typename State,
+ typename Point,
+ typename Iterator
+>
+inline bool point_in_range(Strategy& strategy, State& state,
+ Point const& point, Iterator begin, Iterator end)
+{
+ boost::ignore_unused(strategy);
+
+ Iterator it = begin;
+ for (Iterator previous = it++; it != end; ++previous, ++it)
+ {
+ if (! strategy.apply(point, *previous, *it, state))
+ {
+ // We're probably on the boundary
+ return false;
+ }
+ }
+ return true;
+}
+
+template
+<
+ typename Strategy,
+ typename State,
+ typename Point,
+ typename CoordinateType,
+ typename Iterator
+>
+inline bool point_in_section(Strategy& strategy, State& state,
+ Point const& point, CoordinateType const& point_y,
+ Iterator begin, Iterator end,
+ int direction)
+{
+ if (direction == 0)
+ {
+ // Not a monotonic section, or no change in Y-direction
+ return point_in_range(strategy, state, point, begin, end);
+ }
+
+ // We're in a monotonic section in y-direction
+ Iterator it = begin;
+
+ for (Iterator previous = it++; it != end; ++previous, ++it)
+ {
+ // Depending on sections.direction we can quit for this section
+ CoordinateType const previous_y = geometry::get<1>(*previous);
+
+ if (direction == 1 && point_y < previous_y)
+ {
+ // Section goes upwards, y increases, point is is below section
+ return true;
+ }
+ else if (direction == -1 && point_y > previous_y)
+ {
+ // Section goes downwards, y decreases, point is above section
+ return true;
+ }
+
+ if (! strategy.apply(point, *previous, *it, state))
+ {
+ // We're probably on the boundary
+ return false;
+ }
+ }
+ return true;
+}
+
+
+template <typename Point, typename Original>
+inline int point_in_original(Point const& point, Original const& original)
+{
+ typedef strategy::within::winding<Point> strategy_type;
+
+ typename strategy_type::state_type state;
+ strategy_type strategy;
+
+ if (boost::size(original.m_sections) == 0
+ || boost::size(original.m_ring) - boost::size(original.m_sections) < 16)
+ {
+ // There are no sections, or it does not profit to walk over sections
+ // instead of over points. Boundary of 16 is arbitrary but can influence
+ // performance
+ point_in_range(strategy, state, point,
+ original.m_ring.begin(), original.m_ring.end());
+ return strategy.result(state);
+ }
+
+ typedef typename Original::sections_type sections_type;
+ typedef typename boost::range_iterator<sections_type const>::type iterator_type;
+ typedef typename boost::range_value<sections_type const>::type section_type;
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+
+ coordinate_type const point_y = geometry::get<1>(point);
+
+ // Walk through all monotonic sections of this original
+ for (iterator_type it = boost::begin(original.m_sections);
+ it != boost::end(original.m_sections);
+ ++it)
+ {
+ section_type const& section = *it;
+
+ if (! section.duplicate
+ && section.begin_index < section.end_index
+ && point_y >= geometry::get<min_corner, 1>(section.bounding_box)
+ && point_y <= geometry::get<max_corner, 1>(section.bounding_box))
+ {
+ // y-coordinate of point overlaps with section
+ if (! point_in_section(strategy, state, point, point_y,
+ boost::begin(original.m_ring) + section.begin_index,
+ boost::begin(original.m_ring) + section.end_index + 1,
+ section.directions[0]))
+ {
+ // We're probably on the boundary
+ break;
+ }
+ }
+ }
+
+ return strategy.result(state);
+}
+
+
+template <typename Turns>
+class turn_in_original_visitor
+{
+public:
+ turn_in_original_visitor(Turns& turns)
+ : m_mutable_turns(turns)
+ {}
+
+ template <typename Turn, typename Original>
+ inline void apply(Turn const& turn, Original const& original, bool first = true)
+ {
+ boost::ignore_unused_variable_warning(first);
+
+ if (turn.location != location_ok || turn.within_original)
+ {
+ // Skip all points already processed
+ return;
+ }
+
+ if (geometry::disjoint(turn.robust_point, original.m_box))
+ {
+ // Skip all disjoint
+ return;
+ }
+
+ int const code = point_in_original(turn.robust_point, original);
+
+ if (code == -1)
+ {
+ return;
+ }
+
+ Turn& mutable_turn = m_mutable_turns[turn.turn_index];
+
+ if (code == 0)
+ {
+ // On border of original: always discard
+ mutable_turn.location = location_discard;
+ }
+
+ // Point is inside an original ring
+ if (original.m_is_interior)
+ {
+ mutable_turn.count_in_original--;
+ }
+ else if (original.m_has_interiors)
+ {
+ mutable_turn.count_in_original++;
+ }
+ else
+ {
+ // It is an exterior ring and there are no interior rings.
+ // Then we are completely ready with this turn
+ mutable_turn.within_original = true;
+ mutable_turn.count_in_original = 1;
+ }
+ }
+
+private :
+ Turns& m_mutable_turns;
+};
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TURN_IN_ORIGINAL_VISITOR
diff --git a/3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp b/3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
index 0ace72f637..0aca21ce88 100644
--- a/3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
@@ -9,15 +9,30 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TURN_IN_PIECE_VISITOR
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TURN_IN_PIECE_VISITOR
+
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/arithmetic/dot_product.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/comparable_distance.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
+#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/strategies/buffer.hpp>
+#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
+
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+#include <boost/geometry/strategies/cartesian/side_of_intersection.hpp>
+#endif
+
namespace boost { namespace geometry
{
@@ -27,6 +42,33 @@ namespace boost { namespace geometry
namespace detail { namespace buffer
{
+struct piece_get_box
+{
+ template <typename Box, typename Piece>
+ static inline void apply(Box& total, Piece const& piece)
+ {
+ geometry::expand(total, piece.robust_envelope);
+ }
+};
+
+struct piece_ovelaps_box
+{
+ template <typename Box, typename Piece>
+ static inline bool apply(Box const& box, Piece const& piece)
+ {
+ if (piece.type == strategy::buffer::buffered_flat_end
+ || piece.type == strategy::buffer::buffered_concave)
+ {
+ // Turns cannot be inside a flat end (though they can be on border)
+ // Neither we need to check if they are inside concave helper pieces
+
+ // Skip all pieces not used as soon as possible
+ return false;
+ }
+
+ return ! geometry::detail::disjoint::disjoint_box_box(box, piece.robust_envelope);
+ }
+};
struct turn_get_box
{
@@ -42,70 +84,595 @@ struct turn_ovelaps_box
template <typename Box, typename Turn>
static inline bool apply(Box const& box, Turn const& turn)
{
- return ! geometry::disjoint(box, turn.robust_point);
+ return ! geometry::detail::disjoint::disjoint_point_box(turn.robust_point, box);
}
};
-template <typename Turns, typename Pieces>
-class turn_in_piece_visitor
+
+enum analyse_result
{
- Turns& m_turns; // because partition is currently operating on const input only
- Pieces const& m_pieces; // to check for piece-type
+ analyse_unknown,
+ analyse_continue,
+ analyse_disjoint,
+ analyse_within,
+ analyse_on_original_boundary,
+ analyse_on_offsetted
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ , analyse_near_offsetted
+#endif
+};
- template <typename Point>
- static inline bool projection_on_segment(Point const& subject, Point const& p, Point const& q)
+template <typename Point>
+inline bool in_box(Point const& previous,
+ Point const& current, Point const& point)
+{
+ // Get its box (TODO: this can be prepared-on-demand later)
+ typedef geometry::model::box<Point> box_type;
+ box_type box;
+ geometry::assign_inverse(box);
+ geometry::expand(box, previous);
+ geometry::expand(box, current);
+
+ return geometry::covered_by(point, box);
+}
+
+template <typename Point, typename Turn>
+inline analyse_result check_segment(Point const& previous,
+ Point const& current, Turn const& turn,
+ bool from_monotonic)
+{
+
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ typedef geometry::model::referring_segment<Point const> segment_type;
+ segment_type const p(turn.rob_pi, turn.rob_pj);
+ segment_type const q(turn.rob_qi, turn.rob_qj);
+ segment_type const r(previous, current);
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ if (side == 0)
+ {
+ return analyse_on_offsetted;
+ }
+ if (side == -1 && from_monotonic)
+ {
+ return analyse_within;
+ }
+ if (side == 1 && from_monotonic)
{
- typedef Point vector_type;
- typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+ return analyse_disjoint;
+ }
+ return analyse_continue;
- vector_type v = q;
- vector_type w = subject;
- subtract_point(v, p);
- subtract_point(w, p);
+#else
- coordinate_type const zero = coordinate_type();
- coordinate_type const c1 = dot_product(w, v);
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Point>::type
+ >::type side_strategy;
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+
+ coordinate_type const twice_area
+ = side_strategy::template side_value
+ <
+ coordinate_type,
+ coordinate_type
+ >(previous, current, turn.robust_point);
- if (c1 < zero)
+ if (twice_area == 0)
+ {
+ // Collinear, only on segment if it is covered by its bbox
+ if (in_box(previous, current, turn.robust_point))
{
- return false;
+ return analyse_on_offsetted;
+ }
+ }
+ else if (twice_area < 0)
+ {
+ // It is in the triangle right-of the segment where the
+ // segment is the hypothenusa. Check if it is close
+ // (within rounding-area)
+ if (twice_area * twice_area < geometry::comparable_distance(previous, current)
+ && in_box(previous, current, turn.robust_point))
+ {
+ return analyse_near_offsetted;
}
- coordinate_type const c2 = dot_product(v, v);
- if (c2 < c1)
+ else if (from_monotonic)
{
- return false;
+ return analyse_within;
}
+ }
+ else if (twice_area > 0 && from_monotonic)
+ {
+ // Left of segment
+ return analyse_disjoint;
+ }
+
+ // Not monotonic, on left or right side: continue analysing
+ return analyse_continue;
+#endif
+}
+
+
+class analyse_turn_wrt_point_piece
+{
+public :
+ template <typename Turn, typename Piece>
+ static inline analyse_result apply(Turn const& turn, Piece const& piece)
+ {
+ typedef typename Piece::section_type section_type;
+ typedef typename Turn::robust_point_type point_type;
+ typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
+
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ typedef geometry::model::referring_segment<point_type const> segment_type;
+ segment_type const p(turn.rob_pi, turn.rob_pj);
+ segment_type const q(turn.rob_qi, turn.rob_qj);
+#else
+ typedef strategy::within::winding<point_type> strategy_type;
- return true;
+ typename strategy_type::state_type state;
+ strategy_type strategy;
+ boost::ignore_unused(strategy);
+#endif
+
+ BOOST_GEOMETRY_ASSERT(! piece.sections.empty());
+
+ coordinate_type const point_y = geometry::get<1>(turn.robust_point);
+
+ for (std::size_t s = 0; s < piece.sections.size(); s++)
+ {
+ section_type const& section = piece.sections[s];
+ // If point within vertical range of monotonic section:
+ if (! section.duplicate
+ && section.begin_index < section.end_index
+ && point_y >= geometry::get<min_corner, 1>(section.bounding_box) - 1
+ && point_y <= geometry::get<max_corner, 1>(section.bounding_box) + 1)
+ {
+ for (signed_size_type i = section.begin_index + 1; i <= section.end_index; i++)
+ {
+ point_type const& previous = piece.robust_ring[i - 1];
+ point_type const& current = piece.robust_ring[i];
+
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+
+ // First check if it is in range - if it is not, the
+ // expensive side_of_intersection does not need to be
+ // applied
+ coordinate_type y1 = geometry::get<1>(previous);
+ coordinate_type y2 = geometry::get<1>(current);
+
+ if (y1 > y2)
+ {
+ std::swap(y1, y2);
+ }
+
+ if (point_y >= y1 - 1 && point_y <= y2 + 1)
+ {
+ segment_type const r(previous, current);
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ // Sections are monotonic in y-dimension
+ if (side == 1)
+ {
+ // Left on segment
+ return analyse_disjoint;
+ }
+ else if (side == 0)
+ {
+ // Collinear - TODO: check if really on segment
+ return analyse_on_offsetted;
+ }
+ }
+#else
+ analyse_result code = check_segment(previous, current, turn, false);
+ if (code != analyse_continue)
+ {
+ return code;
+ }
+
+ // Get the state (to determine it is within), we don't have
+ // to cover the on-segment case (covered above)
+ strategy.apply(turn.robust_point, previous, current, state);
+#endif
+ }
+ }
+ }
+
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ // It is nowhere outside, and not on segment, so it is within
+ return analyse_within;
+#else
+ int const code = strategy.result(state);
+ if (code == 1)
+ {
+ return analyse_within;
+ }
+ else if (code == -1)
+ {
+ return analyse_disjoint;
+ }
+
+ // Should normally not occur - on-segment is covered
+ return analyse_unknown;
+#endif
}
+};
- template <typename Point, typename Piece>
- inline bool on_offsetted(Point const& point, Piece const& piece) const
+class analyse_turn_wrt_piece
+{
+ template <typename Point, typename Turn>
+ static inline analyse_result check_helper_segment(Point const& s1,
+ Point const& s2, Turn const& turn,
+ bool is_original,
+ Point const& offsetted)
{
+ boost::ignore_unused(offsetted);
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ typedef geometry::model::referring_segment<Point const> segment_type;
+ segment_type const p(turn.rob_pi, turn.rob_pj);
+ segment_type const q(turn.rob_qi, turn.rob_qj);
+ segment_type const r(s1, s2);
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ if (side == 1)
+ {
+ // left of segment
+ return analyse_disjoint;
+ }
+ else if (side == 0)
+ {
+ // If is collinear, either on segment or before/after
+ typedef geometry::model::box<Point> box_type;
+
+ box_type box;
+ geometry::assign_inverse(box);
+ geometry::expand(box, s1);
+ geometry::expand(box, s2);
+
+ if (geometry::covered_by(turn.robust_point, box))
+ {
+ // Points on helper-segments are considered as within
+ // Points on original boundary are processed differently
+ return is_original
+ ? analyse_on_original_boundary
+ : analyse_within;
+ }
+
+ // It is collinear but not on the segment. Because these
+ // segments are convex, it is outside
+ // Unless the offsetted ring is collinear or concave w.r.t.
+ // helper-segment but that scenario is not yet supported
+ return analyse_disjoint;
+ }
+
+ // right of segment
+ return analyse_continue;
+#else
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<Point>::type
>::type side_strategy;
- for (int i = 1; i < piece.offsetted_count; i++)
+ switch(side_strategy::apply(s1, s2, turn.robust_point))
+ {
+ case 1 :
+ return analyse_disjoint; // left of segment
+ case 0 :
+ {
+ // If is collinear, either on segment or before/after
+ typedef geometry::model::box<Point> box_type;
+
+ box_type box;
+ geometry::assign_inverse(box);
+ geometry::expand(box, s1);
+ geometry::expand(box, s2);
+
+ if (geometry::covered_by(turn.robust_point, box))
+ {
+ // It is on the segment
+ if (! is_original
+ && geometry::comparable_distance(turn.robust_point, offsetted) <= 1)
+ {
+ // It is close to the offsetted-boundary, take
+ // any rounding-issues into account
+ return analyse_near_offsetted;
+ }
+
+ // Points on helper-segments are considered as within
+ // Points on original boundary are processed differently
+ return is_original
+ ? analyse_on_original_boundary
+ : analyse_within;
+ }
+
+ // It is collinear but not on the segment. Because these
+ // segments are convex, it is outside
+ // Unless the offsetted ring is collinear or concave w.r.t.
+ // helper-segment but that scenario is not yet supported
+ return analyse_disjoint;
+ }
+ break;
+ }
+
+ // right of segment
+ return analyse_continue;
+#endif
+ }
+
+ template <typename Turn, typename Piece>
+ static inline analyse_result check_helper_segments(Turn const& turn, Piece const& piece)
+ {
+ typedef typename Turn::robust_point_type point_type;
+ geometry::equal_to<point_type> comparator;
+
+ point_type points[4];
+
+ signed_size_type helper_count = static_cast<signed_size_type>(piece.robust_ring.size())
+ - piece.offsetted_count;
+ if (helper_count == 4)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ points[i] = piece.robust_ring[piece.offsetted_count + i];
+ }
+ }
+ else if (helper_count == 3)
+ {
+ // Triangular piece, assign points but assign second twice
+ for (int i = 0; i < 4; i++)
+ {
+ int index = i < 2 ? i : i - 1;
+ points[i] = piece.robust_ring[piece.offsetted_count + index];
+ }
+ }
+ else
+ {
+ // Some pieces (e.g. around points) do not have helper segments.
+ // Others should have 3 (join) or 4 (side)
+ return analyse_continue;
+ }
+
+ // First check point-equality
+ point_type const& point = turn.robust_point;
+ if (comparator(point, points[0]) || comparator(point, points[3]))
+ {
+ return analyse_on_offsetted;
+ }
+ if (comparator(point, points[1]) || comparator(point, points[2]))
+ {
+ return analyse_on_original_boundary;
+ }
+
+ // Right side of the piece
+ analyse_result result
+ = check_helper_segment(points[0], points[1], turn,
+ false, points[0]);
+ if (result != analyse_continue)
+ {
+ return result;
+ }
+
+ // Left side of the piece
+ result = check_helper_segment(points[2], points[3], turn,
+ false, points[3]);
+ if (result != analyse_continue)
+ {
+ return result;
+ }
+
+ if (! comparator(points[1], points[2]))
{
- Point const& previous = piece.robust_ring[i - 1];
- Point const& current = piece.robust_ring[i];
- int const side = side_strategy::apply(point, previous, current);
- if (side == 0)
+ // Side of the piece at side of original geometry
+ result = check_helper_segment(points[1], points[2], turn,
+ true, point);
+ if (result != analyse_continue)
{
- // Collinear, check if projection falls on it
- if (projection_on_segment(point, previous, current))
+ return result;
+ }
+ }
+
+ // We are within the \/ or |_| shaped piece, where the top is the
+ // offsetted ring.
+ if (! geometry::covered_by(point, piece.robust_offsetted_envelope))
+ {
+ // Not in offsetted-area. This makes a cheap check possible
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<point_type>::type
+ >::type side_strategy;
+
+ switch(side_strategy::apply(points[3], points[0], point))
+ {
+ case 1 : return analyse_disjoint;
+ case -1 : return analyse_within;
+ case 0 : return analyse_disjoint;
+ }
+ }
+
+ return analyse_continue;
+ }
+
+ template <typename Turn, typename Piece, typename Compare>
+ static inline analyse_result check_monotonic(Turn const& turn, Piece const& piece, Compare const& compare)
+ {
+ typedef typename Piece::piece_robust_ring_type ring_type;
+ typedef typename ring_type::const_iterator it_type;
+ it_type end = piece.robust_ring.begin() + piece.offsetted_count;
+ it_type it = std::lower_bound(piece.robust_ring.begin(),
+ end,
+ turn.robust_point,
+ compare);
+
+ if (it != end
+ && it != piece.robust_ring.begin())
+ {
+ // iterator points to point larger than point
+ // w.r.t. specified direction, and prev points to a point smaller
+ // We now know if it is inside/outside
+ it_type prev = it - 1;
+ return check_segment(*prev, *it, turn, true);
+ }
+ return analyse_continue;
+ }
+
+public :
+ template <typename Turn, typename Piece>
+ static inline analyse_result apply(Turn const& turn, Piece const& piece)
+ {
+ typedef typename Turn::robust_point_type point_type;
+ analyse_result code = check_helper_segments(turn, piece);
+ if (code != analyse_continue)
+ {
+ return code;
+ }
+
+ geometry::equal_to<point_type> comparator;
+
+ if (piece.offsetted_count > 8)
+ {
+ // If the offset contains some points and is monotonic, we try
+ // to avoid walking all points linearly.
+ // We try it only once.
+ if (piece.is_monotonic_increasing[0])
+ {
+ code = check_monotonic(turn, piece, geometry::less<point_type, 0>());
+ if (code != analyse_continue) return code;
+ }
+ else if (piece.is_monotonic_increasing[1])
+ {
+ code = check_monotonic(turn, piece, geometry::less<point_type, 1>());
+ if (code != analyse_continue) return code;
+ }
+ else if (piece.is_monotonic_decreasing[0])
+ {
+ code = check_monotonic(turn, piece, geometry::greater<point_type, 0>());
+ if (code != analyse_continue) return code;
+ }
+ else if (piece.is_monotonic_decreasing[1])
+ {
+ code = check_monotonic(turn, piece, geometry::greater<point_type, 1>());
+ if (code != analyse_continue) return code;
+ }
+ }
+
+ // It is small or not monotonic, walk linearly through offset
+ // TODO: this will be combined with winding strategy
+
+ for (signed_size_type i = 1; i < piece.offsetted_count; i++)
+ {
+ point_type const& previous = piece.robust_ring[i - 1];
+ point_type const& current = piece.robust_ring[i];
+
+ // The robust ring can contain duplicates
+ // (on which any side or side-value would return 0)
+ if (! comparator(previous, current))
+ {
+ code = check_segment(previous, current, turn, false);
+ if (code != analyse_continue)
{
- return true;
+ return code;
}
}
+ }
+
+ return analyse_unknown;
+ }
+
+};
+
+
+template <typename Turns, typename Pieces>
+class turn_in_piece_visitor
+{
+ Turns& m_turns; // because partition is currently operating on const input only
+ Pieces const& m_pieces; // to check for piece-type
+ template <typename Operation, typename Piece>
+ inline bool skip(Operation const& op, Piece const& piece) const
+ {
+ if (op.piece_index == piece.index)
+ {
+ return true;
}
+ Piece const& pc = m_pieces[op.piece_index];
+ if (pc.left_index == piece.index || pc.right_index == piece.index)
+ {
+ if (pc.type == strategy::buffer::buffered_flat_end)
+ {
+ // If it is a flat end, don't compare against its neighbor:
+ // it will always be located on one of the helper segments
+ return true;
+ }
+ if (pc.type == strategy::buffer::buffered_concave)
+ {
+ // If it is concave, the same applies: the IP will be
+ // located on one of the helper segments
+ return true;
+ }
+ }
+
return false;
}
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ // NOTE: this function returns a side value in {-1, 0, 1}
+ template <typename Turn, typename Piece>
+ static inline int turn_in_convex_piece(Turn const& turn,
+ Piece const& piece)
+ {
+ typedef typename Turn::robust_point_type point_type;
+ typedef typename Piece::piece_robust_ring_type ring_type;
+ typedef geometry::model::referring_segment<point_type const> segment;
+
+ segment const p(turn.rob_pi, turn.rob_pj);
+ segment const q(turn.rob_qi, turn.rob_qj);
+
+ typedef typename boost::range_iterator<ring_type const>::type iterator_type;
+ iterator_type it = boost::begin(piece.robust_ring);
+ iterator_type end = boost::end(piece.robust_ring);
+
+ // A robust ring is always closed, and always clockwise
+ for (iterator_type previous = it++; it != end; ++previous, ++it)
+ {
+ geometry::equal_to<point_type> comparator;
+ if (comparator(*previous, *it))
+ {
+ // Points are the same
+ continue;
+ }
+
+ segment r(*previous, *it);
+
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ if (side == 1)
+ {
+ // IP is left of segment, so it is outside
+ return -1; // outside
+ }
+ else if (side == 0)
+ {
+ // IP is collinear with segment. TODO: we should analyze this further
+ // For now we use the fallback point
+ if (in_box(*previous, *it, turn.robust_point))
+ {
+ return 0;
+ }
+ else
+ {
+ return -1; // outside
+ }
+ }
+ }
+ return 1; // inside
+ }
+#endif
+
public:
@@ -128,62 +695,96 @@ public:
if (piece.type == strategy::buffer::buffered_flat_end
|| piece.type == strategy::buffer::buffered_concave)
{
- // Turns cannot be inside a flat end (though they can be on border)
- // Neither we need to check if they are inside concave helper pieces
+ // Turns cannot be located within flat-end or concave pieces
+ return;
+ }
+
+ if (! geometry::covered_by(turn.robust_point, piece.robust_envelope))
+ {
+ // Easy check: if the turn is not in the envelope, we can safely return
+ return;
+ }
+
+ if (skip(turn.operations[0], piece) || skip(turn.operations[1], piece))
+ {
return;
}
- bool neighbour = false;
- for (int i = 0; i < 2; i++)
+ // TODO: mutable_piece to make some on-demand preparations in analyse
+ Turn& mutable_turn = m_turns[turn.turn_index];
+
+ if (piece.type == geometry::strategy::buffer::buffered_point)
{
- // Don't compare against one of the two source-pieces
- if (turn.operations[i].piece_index == piece.index)
+ // Optimization for buffer around points: if distance from center
+ // is not between min/max radius, the result is clear
+ typedef typename default_comparable_distance_result
+ <
+ typename Turn::robust_point_type
+ >::type distance_type;
+
+ distance_type const cd
+ = geometry::comparable_distance(piece.robust_center,
+ turn.robust_point);
+
+ if (cd < piece.robust_min_comparable_radius)
{
+ mutable_turn.count_within++;
return;
}
-
- typename boost::range_value<Pieces>::type const& pc
- = m_pieces[turn.operations[i].piece_index];
- if (pc.left_index == piece.index
- || pc.right_index == piece.index)
+ if (cd > piece.robust_max_comparable_radius)
{
- if (pc.type == strategy::buffer::buffered_flat_end)
- {
- // If it is a flat end, don't compare against its neighbor:
- // it will always be located on one of the helper segments
- return;
- }
- neighbour = true;
+ return;
}
}
- int geometry_code = detail::within::point_in_geometry(turn.robust_point, piece.robust_ring);
+ analyse_result analyse_code =
+ piece.type == geometry::strategy::buffer::buffered_point
+ ? analyse_turn_wrt_point_piece::apply(turn, piece)
+ : analyse_turn_wrt_piece::apply(turn, piece);
- if (geometry_code == -1)
+ switch(analyse_code)
{
- return;
+ case analyse_disjoint :
+ return;
+ case analyse_on_offsetted :
+ mutable_turn.count_on_offsetted++; // value is not used anymore
+ return;
+ case analyse_on_original_boundary :
+ mutable_turn.count_on_original_boundary++;
+ return;
+ case analyse_within :
+ mutable_turn.count_within++;
+ return;
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ case analyse_near_offsetted :
+ mutable_turn.count_within_near_offsetted++;
+ return;
+#endif
+ default :
+ break;
}
- Turn& mutable_turn = m_turns[turn.turn_index];
- if (geometry_code == 0 && ! neighbour)
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ // We don't know (yet)
+ int geometry_code = 0;
+ if (piece.is_convex)
+ {
+ geometry_code = turn_in_convex_piece(turn, piece);
+ }
+ else
{
- // If it is on the border and they are neighbours, it should be
- // on the offsetted ring
- if (! on_offsetted(turn.robust_point, piece))
- {
- // It is on the border but not on the offsetted ring.
- // Then it is somewhere on the helper-segments
- // Classify it as inside
- geometry_code = 1;
- mutable_turn.count_on_helper++;
- }
+ // TODO: this point_in_geometry is a performance-bottleneck here and
+ // will be replaced completely by extending analyse_piece functionality
+ geometry_code = detail::within::point_in_geometry(turn.robust_point, piece.robust_ring);
}
+#else
+ int geometry_code = detail::within::point_in_geometry(turn.robust_point, piece.robust_ring);
+#endif
- switch (geometry_code)
+ if (geometry_code == 1)
{
- case 1 : mutable_turn.count_within++; break;
- case 0 : mutable_turn.count_on_offsetted++; break;
+ mutable_turn.count_within++;
}
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/centroid/translating_transformer.hpp b/3party/boost/boost/geometry/algorithms/detail/centroid/translating_transformer.hpp
new file mode 100644
index 0000000000..56a7e3ec91
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/centroid/translating_transformer.hpp
@@ -0,0 +1,119 @@
+// 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.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_CENTROID_TRANSLATING_TRANSFORMER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CENTROID_TRANSLATING_TRANSFORMER_HPP
+
+
+#include <cstddef>
+
+#include <boost/core/addressof.hpp>
+#include <boost/core/ref.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+
+#include <boost/geometry/iterators/point_iterator.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace centroid
+{
+
+
+// NOTE: There is no need to translate in other coordinate systems than
+// cartesian. But if it was needed then one should translate using
+// CS-specific technique, e.g. in spherical/geographic a translation
+// vector should contain coordinates being multiplies of 2PI or 360 deg.
+template <typename Geometry,
+ typename CastedTag = typename tag_cast
+ <
+ typename tag<Geometry>::type,
+ areal_tag
+ >::type,
+ typename CSTag = typename cs_tag<Geometry>::type>
+struct translating_transformer
+{
+ typedef typename geometry::point_type<Geometry>::type point_type;
+ typedef boost::reference_wrapper<point_type const> result_type;
+
+ explicit translating_transformer(Geometry const&) {}
+ explicit translating_transformer(point_type const&) {}
+
+ result_type apply(point_type const& pt) const
+ {
+ return result_type(pt);
+ }
+
+ template <typename ResPt>
+ void apply_reverse(ResPt &) const {}
+};
+
+// Specialization for Areal Geometries in cartesian CS
+template <typename Geometry>
+struct translating_transformer<Geometry, areal_tag, cartesian_tag>
+{
+ typedef typename geometry::point_type<Geometry>::type point_type;
+ typedef point_type result_type;
+
+ explicit translating_transformer(Geometry const& geom)
+ : m_origin(NULL)
+ {
+ geometry::point_iterator<Geometry const>
+ pt_it = geometry::points_begin(geom);
+ if ( pt_it != geometry::points_end(geom) )
+ {
+ m_origin = boost::addressof(*pt_it);
+ }
+ }
+
+ explicit translating_transformer(point_type const& origin)
+ : m_origin(boost::addressof(origin))
+ {}
+
+ result_type apply(point_type const& pt) const
+ {
+ point_type res = pt;
+ if ( m_origin )
+ geometry::subtract_point(res, *m_origin);
+ return res;
+ }
+
+ template <typename ResPt>
+ void apply_reverse(ResPt & res_pt) const
+ {
+ if ( m_origin )
+ geometry::add_point(res_pt, *m_origin);
+ }
+
+ const point_type * m_origin;
+};
+
+
+}} // namespace detail::centroid
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CENTROID_TRANSLATING_TRANSFORMER_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/check_iterator_range.hpp b/3party/boost/boost/geometry/algorithms/detail/check_iterator_range.hpp
index 09ea7f79a0..9bd1d7ae27 100644
--- a/3party/boost/boost/geometry/algorithms/detail/check_iterator_range.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/check_iterator_range.hpp
@@ -33,7 +33,7 @@ struct check_iterator_range
{
for (InputIterator it = first; it != beyond; ++it)
{
- if ( !Predicate::apply(*it) )
+ if (! Predicate::apply(*it))
{
return false;
}
@@ -54,7 +54,7 @@ struct check_iterator_range
for (InputIterator it = first; it != beyond; ++it)
{
- if ( !predicate.apply(*it) )
+ if (! predicate.apply(*it))
{
return false;
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp b/3party/boost/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp
new file mode 100644
index 0000000000..4ac5ac6976
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp
@@ -0,0 +1,145 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP
+
+#include <iterator>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/dispatch/distance.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace closest_feature
+{
+
+
+
+// returns the range iterator the realizes the closest
+// distance between the geometry and the element of the range
+class geometry_to_range
+{
+private:
+ template
+ <
+ typename Geometry,
+ typename RangeIterator,
+ typename Strategy,
+ typename Distance
+ >
+ static inline void apply(Geometry const& geometry,
+ RangeIterator first,
+ RangeIterator last,
+ Strategy const& strategy,
+ RangeIterator& it_min,
+ Distance& dist_min)
+ {
+ BOOST_GEOMETRY_ASSERT( first != last );
+
+ Distance const zero = Distance(0);
+
+ // start with first distance
+ it_min = first;
+ dist_min = dispatch::distance
+ <
+ Geometry,
+ typename std::iterator_traits<RangeIterator>::value_type,
+ Strategy
+ >::apply(geometry, *it_min, strategy);
+
+ // check if other elements in the range are closer
+ for (RangeIterator it = ++first; it != last; ++it)
+ {
+ Distance dist = dispatch::distance
+ <
+ Geometry,
+ typename std::iterator_traits<RangeIterator>::value_type,
+ Strategy
+ >::apply(geometry, *it, strategy);
+
+ if (geometry::math::equals(dist, zero))
+ {
+ dist_min = dist;
+ it_min = it;
+ return;
+ }
+ else if (dist < dist_min)
+ {
+ dist_min = dist;
+ it_min = it;
+ }
+ }
+ }
+
+public:
+ template
+ <
+ typename Geometry,
+ typename RangeIterator,
+ typename Strategy,
+ typename Distance
+ >
+ static inline RangeIterator apply(Geometry const& geometry,
+ RangeIterator first,
+ RangeIterator last,
+ Strategy const& strategy,
+ Distance& dist_min)
+ {
+ RangeIterator it_min;
+ apply(geometry, first, last, strategy, it_min, dist_min);
+
+ return it_min;
+ }
+
+
+ template
+ <
+ typename Geometry,
+ typename RangeIterator,
+ typename Strategy
+ >
+ static inline RangeIterator apply(Geometry const& geometry,
+ RangeIterator first,
+ RangeIterator last,
+ Strategy const& strategy)
+ {
+ typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<Geometry>::type,
+ typename point_type
+ <
+ typename std::iterator_traits
+ <
+ RangeIterator
+ >::value_type
+ >::type
+ >::type dist_min;
+
+ return apply(geometry, first, last, strategy, dist_min);
+ }
+};
+
+
+
+}} // namespace detail::closest_feature
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp b/3party/boost/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp
new file mode 100644
index 0000000000..df67890138
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp
@@ -0,0 +1,250 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_POINT_TO_RANGE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_POINT_TO_RANGE_HPP
+
+#include <utility>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace closest_feature
+{
+
+
+// returns the segment (pair of iterators) that realizes the closest
+// distance of the point to the range
+template
+<
+ typename Point,
+ typename Range,
+ closure_selector Closure,
+ typename Strategy
+>
+class point_to_point_range
+{
+protected:
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+ template <typename Distance>
+ static inline void apply(Point const& point,
+ iterator_type first,
+ iterator_type last,
+ Strategy const& strategy,
+ iterator_type& it_min1,
+ iterator_type& it_min2,
+ Distance& dist_min)
+ {
+ BOOST_GEOMETRY_ASSERT( first != last );
+
+ Distance const zero = Distance(0);
+
+ iterator_type it = first;
+ iterator_type prev = it++;
+ if (it == last)
+ {
+ it_min1 = it_min2 = first;
+ dist_min = strategy.apply(point, *first, *first);
+ return;
+ }
+
+ // start with first segment distance
+ dist_min = strategy.apply(point, *prev, *it);
+ iterator_type prev_min_dist = prev;
+
+ // check if other segments are closer
+ for (++prev, ++it; it != last; ++prev, ++it)
+ {
+ Distance dist = strategy.apply(point, *prev, *it);
+ if (geometry::math::equals(dist, zero))
+ {
+ dist_min = zero;
+ it_min1 = prev;
+ it_min2 = it;
+ return;
+ }
+ else if (dist < dist_min)
+ {
+ dist_min = dist;
+ prev_min_dist = prev;
+ }
+ }
+
+ it_min1 = it_min2 = prev_min_dist;
+ ++it_min2;
+ }
+
+public:
+ typedef typename std::pair<iterator_type, iterator_type> return_type;
+
+ template <typename Distance>
+ static inline return_type apply(Point const& point,
+ iterator_type first,
+ iterator_type last,
+ Strategy const& strategy,
+ Distance& dist_min)
+ {
+ iterator_type it_min1, it_min2;
+ apply(point, first, last, strategy, it_min1, it_min2, dist_min);
+
+ return std::make_pair(it_min1, it_min2);
+ }
+
+ static inline return_type apply(Point const& point,
+ iterator_type first,
+ iterator_type last,
+ Strategy const& strategy)
+ {
+ typename strategy::distance::services::return_type
+ <
+ Strategy,
+ Point,
+ typename boost::range_value<Range>::type
+ >::type dist_min;
+
+ return apply(point, first, last, strategy, dist_min);
+ }
+
+ template <typename Distance>
+ static inline return_type apply(Point const& point,
+ Range const& range,
+ Strategy const& strategy,
+ Distance& dist_min)
+ {
+ return apply(point,
+ boost::begin(range),
+ boost::end(range),
+ strategy,
+ dist_min);
+ }
+
+ static inline return_type apply(Point const& point,
+ Range const& range,
+ Strategy const& strategy)
+ {
+ return apply(point, boost::begin(range), boost::end(range), strategy);
+ }
+};
+
+
+
+// specialization for open ranges
+template <typename Point, typename Range, typename Strategy>
+class point_to_point_range<Point, Range, open, Strategy>
+ : point_to_point_range<Point, Range, closed, Strategy>
+{
+private:
+ typedef point_to_point_range<Point, Range, closed, Strategy> base_type;
+ typedef typename base_type::iterator_type iterator_type;
+
+ template <typename Distance>
+ static inline void apply(Point const& point,
+ iterator_type first,
+ iterator_type last,
+ Strategy const& strategy,
+ iterator_type& it_min1,
+ iterator_type& it_min2,
+ Distance& dist_min)
+ {
+ BOOST_GEOMETRY_ASSERT( first != last );
+
+ base_type::apply(point, first, last, strategy,
+ it_min1, it_min2, dist_min);
+
+ iterator_type it_back = --last;
+ Distance const zero = Distance(0);
+ Distance dist = strategy.apply(point, *it_back, *first);
+
+ if (geometry::math::equals(dist, zero))
+ {
+ dist_min = zero;
+ it_min1 = it_back;
+ it_min2 = first;
+ }
+ else if (dist < dist_min)
+ {
+ dist_min = dist;
+ it_min1 = it_back;
+ it_min2 = first;
+ }
+ }
+
+public:
+ typedef typename std::pair<iterator_type, iterator_type> return_type;
+
+ template <typename Distance>
+ static inline return_type apply(Point const& point,
+ iterator_type first,
+ iterator_type last,
+ Strategy const& strategy,
+ Distance& dist_min)
+ {
+ iterator_type it_min1, it_min2;
+
+ apply(point, first, last, strategy, it_min1, it_min2, dist_min);
+
+ return std::make_pair(it_min1, it_min2);
+ }
+
+ static inline return_type apply(Point const& point,
+ iterator_type first,
+ iterator_type last,
+ Strategy const& strategy)
+ {
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ Point,
+ typename boost::range_value<Range>::type
+ >::type distance_return_type;
+
+ distance_return_type dist_min;
+
+ return apply(point, first, last, strategy, dist_min);
+ }
+
+ template <typename Distance>
+ static inline return_type apply(Point const& point,
+ Range const& range,
+ Strategy const& strategy,
+ Distance& dist_min)
+ {
+ return apply(point,
+ boost::begin(range),
+ boost::end(range),
+ strategy,
+ dist_min);
+ }
+
+ static inline return_type apply(Point const& point,
+ Range const& range,
+ Strategy const& strategy)
+ {
+ return apply(point, boost::begin(range), boost::end(range), strategy);
+ }
+};
+
+
+}} // namespace detail::closest_feature
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_POINT_TO_RANGE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp b/3party/boost/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp
new file mode 100644
index 0000000000..26b8684828
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp
@@ -0,0 +1,196 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_RANGE_TO_RANGE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_RANGE_TO_RANGE_HPP
+
+#include <cstddef>
+
+#include <iterator>
+#include <utility>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/algorithms/dispatch/distance.hpp>
+#include <boost/geometry/index/rtree.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace closest_feature
+{
+
+
+// returns a pair of a objects where the first is an object of the
+// r-tree range and the second an object of the query range that
+// realizes the closest feature of the two ranges
+class range_to_range_rtree
+{
+private:
+ template
+ <
+ typename RTreeRangeIterator,
+ typename QueryRangeIterator,
+ typename Strategy,
+ typename RTreeValueType,
+ typename Distance
+ >
+ static inline void apply(RTreeRangeIterator rtree_first,
+ RTreeRangeIterator rtree_last,
+ QueryRangeIterator queries_first,
+ QueryRangeIterator queries_last,
+ Strategy const& strategy,
+ RTreeValueType& rtree_min,
+ QueryRangeIterator& qit_min,
+ Distance& dist_min)
+ {
+ typedef index::rtree<RTreeValueType, index::linear<8> > rtree_type;
+
+ BOOST_GEOMETRY_ASSERT( rtree_first != rtree_last );
+ BOOST_GEOMETRY_ASSERT( queries_first != queries_last );
+
+ Distance const zero = Distance(0);
+ dist_min = zero;
+
+ // create -- packing algorithm
+ rtree_type rt(rtree_first, rtree_last);
+
+ RTreeValueType t_v;
+ bool first = true;
+
+ for (QueryRangeIterator qit = queries_first;
+ qit != queries_last; ++qit, first = false)
+ {
+ std::size_t n = rt.query(index::nearest(*qit, 1), &t_v);
+
+ BOOST_GEOMETRY_ASSERT( n > 0 );
+ // n above is unused outside BOOST_GEOMETRY_ASSERT,
+ // hence the call to boost::ignore_unused below
+ //
+ // however, t_v (initialized by the call to rt.query(...))
+ // is used below, which is why we cannot put the call to
+ // rt.query(...) inside BOOST_GEOMETRY_ASSERT
+ boost::ignore_unused(n);
+
+ Distance dist = dispatch::distance
+ <
+ RTreeValueType,
+ typename std::iterator_traits
+ <
+ QueryRangeIterator
+ >::value_type,
+ Strategy
+ >::apply(t_v, *qit, strategy);
+
+ if (first || dist < dist_min)
+ {
+ dist_min = dist;
+ rtree_min = t_v;
+ qit_min = qit;
+ if ( math::equals(dist_min, zero) )
+ {
+ return;
+ }
+ }
+ }
+ }
+
+public:
+ template <typename RTreeRangeIterator, typename QueryRangeIterator>
+ struct return_type
+ {
+ typedef std::pair
+ <
+ typename std::iterator_traits<RTreeRangeIterator>::value_type,
+ QueryRangeIterator
+ > type;
+ };
+
+
+ template
+ <
+ typename RTreeRangeIterator,
+ typename QueryRangeIterator,
+ typename Strategy,
+ typename Distance
+ >
+ static inline typename return_type
+ <
+ RTreeRangeIterator, QueryRangeIterator
+ >::type apply(RTreeRangeIterator rtree_first,
+ RTreeRangeIterator rtree_last,
+ QueryRangeIterator queries_first,
+ QueryRangeIterator queries_last,
+ Strategy const& strategy,
+ Distance& dist_min)
+ {
+ typedef typename std::iterator_traits
+ <
+ RTreeRangeIterator
+ >::value_type rtree_value_type;
+
+ rtree_value_type rtree_min;
+ QueryRangeIterator qit_min;
+
+ apply(rtree_first, rtree_last, queries_first, queries_last,
+ strategy, rtree_min, qit_min, dist_min);
+
+ return std::make_pair(rtree_min, qit_min);
+ }
+
+
+ template
+ <
+ typename RTreeRangeIterator,
+ typename QueryRangeIterator,
+ typename Strategy
+ >
+ static inline typename return_type
+ <
+ RTreeRangeIterator, QueryRangeIterator
+ >::type apply(RTreeRangeIterator rtree_first,
+ RTreeRangeIterator rtree_last,
+ QueryRangeIterator queries_first,
+ QueryRangeIterator queries_last,
+ Strategy const& strategy)
+ {
+ typedef typename std::iterator_traits
+ <
+ RTreeRangeIterator
+ >::value_type rtree_value_type;
+
+ typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<rtree_value_type>::type,
+ typename point_type
+ <
+ typename std::iterator_traits
+ <
+ QueryRangeIterator
+ >::value_type
+ >::type
+ >::type dist_min;
+
+ return apply(rtree_first, rtree_last, queries_first, queries_last,
+ strategy, dist_min);
+ }
+};
+
+
+}} // namespace detail::closest_feature
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_RANGE_TO_RANGE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/comparable_distance/interface.hpp b/3party/boost/boost/geometry/algorithms/detail/comparable_distance/interface.hpp
index 1a57c8f4b3..c443a54e58 100644
--- a/3party/boost/boost/geometry/algorithms/detail/comparable_distance/interface.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/comparable_distance/interface.hpp
@@ -232,13 +232,13 @@ struct comparable_distance
template
<
- BOOST_VARIANT_ENUM_PARAMS(typename A),
- BOOST_VARIANT_ENUM_PARAMS(typename B)
+ BOOST_VARIANT_ENUM_PARAMS(typename T1),
+ BOOST_VARIANT_ENUM_PARAMS(typename T2)
>
struct comparable_distance
<
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(A)>,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(B)>
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
{
template <typename Strategy>
@@ -246,8 +246,8 @@ struct comparable_distance
<
typename comparable_distance_result
<
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(A)>,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(B)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
Strategy
>::type
>
@@ -279,12 +279,12 @@ struct comparable_distance
template <typename Strategy>
static inline typename comparable_distance_result
<
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(A)>,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(B)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
Strategy
>::type
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(A)> const& geometry1,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(B)> const& geometry2,
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
return apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
diff --git a/3party/boost/boost/geometry/algorithms/detail/counting.hpp b/3party/boost/boost/geometry/algorithms/detail/counting.hpp
new file mode 100644
index 0000000000..dc5bb26c10
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/counting.hpp
@@ -0,0 +1,107 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_COUNTING_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COUNTING_HPP
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace counting
+{
+
+
+template <std::size_t D>
+struct other_count
+{
+ template <typename Geometry>
+ static inline std::size_t apply(Geometry const&)
+ {
+ return D;
+ }
+
+ template <typename Geometry>
+ static inline std::size_t apply(Geometry const&, bool)
+ {
+ return D;
+ }
+};
+
+
+template <typename RangeCount>
+struct polygon_count
+{
+ template <typename Polygon>
+ static inline std::size_t apply(Polygon const& poly)
+ {
+ std::size_t n = RangeCount::apply(exterior_ring(poly));
+
+ typename interior_return_type<Polygon const>::type
+ rings = interior_rings(poly);
+ for (typename detail::interior_iterator<Polygon const>::type
+ it = boost::begin(rings); it != boost::end(rings); ++it)
+ {
+ n += RangeCount::apply(*it);
+ }
+
+ return n;
+ }
+};
+
+
+template <typename SingleCount>
+struct multi_count
+{
+ template <typename MultiGeometry>
+ static inline std::size_t apply(MultiGeometry const& geometry)
+ {
+ std::size_t n = 0;
+ for (typename boost::range_iterator<MultiGeometry const>::type
+ it = boost::begin(geometry);
+ it != boost::end(geometry);
+ ++it)
+ {
+ n += SingleCount::apply(*it);
+ }
+ return n;
+ }
+};
+
+
+}} // namespace detail::counting
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COUNTING_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/course.hpp b/3party/boost/boost/geometry/algorithms/detail/course.hpp
new file mode 100644
index 0000000000..37424941bd
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/course.hpp
@@ -0,0 +1,40 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_COURSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COURSE_HPP
+
+#include <boost/geometry/algorithms/detail/azimuth.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+/// Calculate course (bearing) between two points.
+///
+/// NOTE: left for convenience and temporary backward compatibility
+template <typename ReturnType, typename Point1, typename Point2>
+inline ReturnType course(Point1 const& p1, Point2 const& p2)
+{
+ return azimuth<ReturnType>(p1, p2);
+}
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COURSE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp
index 140d87daf2..284858a130 100644
--- a/3party/boost/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp
@@ -23,9 +23,9 @@
#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/algorithms/within.hpp>
+#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/detail/for_each_range.hpp>
-#include <boost/geometry/algorithms/point_on_surface.hpp>
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
@@ -42,21 +42,21 @@ namespace detail { namespace disjoint
template<typename Geometry>
struct check_each_ring_for_within
{
- bool has_within;
+ bool not_disjoint;
Geometry const& m_geometry;
inline check_each_ring_for_within(Geometry const& g)
- : has_within(false)
+ : not_disjoint(false)
, m_geometry(g)
{}
template <typename Range>
inline void apply(Range const& range)
{
- if ( geometry::within(geometry::return_point_on_surface(range), m_geometry) )
- {
- has_within = true;
- }
+ typename point_type<Range>::type pt;
+ not_disjoint = not_disjoint
+ || ( geometry::point_on_border(pt, range)
+ && geometry::covered_by(pt, m_geometry) );
}
};
@@ -68,7 +68,7 @@ inline bool rings_containing(FirstGeometry const& geometry1,
{
check_each_ring_for_within<FirstGeometry> checker(geometry1);
geometry::detail::for_each_range(geometry2, checker);
- return checker.has_within;
+ return checker.not_disjoint;
}
@@ -87,8 +87,8 @@ struct general_areal
// If there is no intersection of segments, they might located
// inside each other
- // We check that using a point on the surface, and see if that is inside
- // the other geometry. And vice versa.
+ // We check that using a point on the border (external boundary),
+ // and see if that is contained in the other geometry. And vice versa.
if ( rings_containing(geometry1, geometry2)
|| rings_containing(geometry2, geometry1) )
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/box_box.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/box_box.hpp
index ccff9799fd..84671f257e 100644
--- a/3party/boost/boost/geometry/algorithms/detail/disjoint/box_box.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/box_box.hpp
@@ -74,7 +74,7 @@ struct box_box<Box1, Box2, DimensionCount, DimensionCount>
/*!
- \brief Internal utility function to detect of boxes are disjoint
+ \brief Internal utility function to detect if boxes are disjoint
\note Is used from other algorithms, declared separately
to avoid circular references
*/
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/implementation.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/implementation.hpp
index 0c8079b8e4..d482c4a5a9 100644
--- a/3party/boost/boost/geometry/algorithms/detail/disjoint/implementation.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/implementation.hpp
@@ -26,6 +26,7 @@
#include <boost/geometry/algorithms/detail/disjoint/linear_areal.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/interface.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/interface.hpp
index ec9057ba0d..96d6881296 100644
--- a/3party/boost/boost/geometry/algorithms/detail/disjoint/interface.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/interface.hpp
@@ -23,8 +23,8 @@
#include <cstddef>
-#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp
index eefd351b8d..6a48b684a1 100644
--- a/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2015.
+// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -31,16 +31,20 @@
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
-#include <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
+#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
+
+#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
-#include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
@@ -48,25 +52,59 @@
namespace boost { namespace geometry
{
-
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace disjoint
{
+template <typename Geometry1, typename Geometry2,
+ typename Tag1 = typename tag<Geometry1>::type,
+ typename Tag1OrMulti = typename tag_cast<Tag1, multi_tag>::type>
+struct disjoint_no_intersections_policy
+{
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ {
+ typedef typename point_type<Geometry1>::type point1_type;
+ point1_type p;
+ geometry::point_on_border(p, g1);
+ return !geometry::covered_by(p, g2);
+ }
+};
-template<typename Geometry1, typename Geometry2>
+template <typename Geometry1, typename Geometry2, typename Tag1>
+struct disjoint_no_intersections_policy<Geometry1, Geometry2, Tag1, multi_tag>
+{
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ {
+ // TODO: use partition or rtree on g2
+ typedef typename boost::range_iterator<Geometry1 const>::type iterator;
+ for ( iterator it = boost::begin(g1) ; it != boost::end(g1) ; ++it )
+ {
+ typedef typename boost::range_value<Geometry1 const>::type value_type;
+ if ( ! disjoint_no_intersections_policy<value_type const, Geometry2>
+ ::apply(*it, g2) )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+};
+
+
+template<typename Geometry1, typename Geometry2,
+ typename NoIntersectionsPolicy
+ = disjoint_no_intersections_policy<Geometry1, Geometry2> >
struct disjoint_linear_areal
{
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
{
// if there are intersections - return false
if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2) )
+ {
return false;
+ }
- typedef typename point_type<Geometry1>::type point1_type;
- point1_type p;
- geometry::point_on_border(p, g1);
- return !geometry::covered_by(p, g2);
+ return NoIntersectionsPolicy::apply(g1, g2);
}
};
@@ -88,38 +126,28 @@ template <typename Segment, typename Polygon>
class disjoint_segment_areal<Segment, Polygon, polygon_tag>
{
private:
- template <typename RingIterator>
- static inline bool check_interior_rings(RingIterator first,
- RingIterator beyond,
- Segment const& segment)
- {
- for (RingIterator it = first; it != beyond; ++it)
- {
- if ( !disjoint_range_segment_or_box
- <
- typename std::iterator_traits
- <
- RingIterator
- >::value_type,
- closure<Polygon>::value,
- Segment
- >::apply(*it, segment) )
- {
- return false;
- }
- }
- return true;
- }
-
-
template <typename InteriorRings>
static inline
bool check_interior_rings(InteriorRings const& interior_rings,
Segment const& segment)
{
- return check_interior_rings(boost::begin(interior_rings),
- boost::end(interior_rings),
- segment);
+ typedef typename boost::range_value<InteriorRings>::type ring_type;
+
+ typedef unary_disjoint_geometry_to_query_geometry
+ <
+ Segment,
+ disjoint_range_segment_or_box
+ <
+ ring_type, closure<ring_type>::value, Segment
+ >
+ > unary_predicate_type;
+
+ return check_iterator_range
+ <
+ unary_predicate_type
+ >::apply(boost::begin(interior_rings),
+ boost::end(interior_rings),
+ unary_predicate_type(segment));
}
@@ -155,7 +183,7 @@ struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
static inline
bool apply(Segment const& segment, MultiPolygon const& multipolygon)
{
- return disjoint_multirange_segment_or_box
+ return multirange_constant_size_geometry
<
MultiPolygon, Segment
>::apply(multipolygon, segment);
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp
index ad84d7191d..91f985edb8 100644
--- a/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp
@@ -98,11 +98,10 @@ struct assign_disjoint_policy
typename Info,
typename Point1,
typename Point2,
- typename IntersectionInfo,
- typename DirInfo
+ typename IntersectionInfo
>
static inline void apply(Info& , Point1 const& , Point2 const&,
- IntersectionInfo const&, DirInfo const&)
+ IntersectionInfo const&)
{}
};
@@ -115,28 +114,42 @@ struct disjoint_linear
{
typedef typename geometry::point_type<Geometry1>::type point_type;
typedef detail::no_rescale_policy rescale_policy_type;
+ typedef typename geometry::segment_ratio_type
+ <
+ point_type, rescale_policy_type
+ >::type segment_ratio_type;
typedef overlay::turn_info
- <
- point_type,
- typename segment_ratio_type<point_type, rescale_policy_type>::type
- > turn_info;
- std::deque<turn_info> turns;
+ <
+ point_type,
+ segment_ratio_type,
+ typename detail::get_turns::turn_operation_type
+ <
+ Geometry1, Geometry2, segment_ratio_type
+ >::type
+ > turn_info_type;
- static const bool reverse1 = overlay::do_reverse<geometry::point_order<Geometry1>::value>::value; // should be false
- static const bool reverse2 = overlay::do_reverse<geometry::point_order<Geometry2>::value>::value; // should be false
+ std::deque<turn_info_type> turns;
// Specify two policies:
// 1) Stop at any intersection
// 2) In assignment, include also degenerate points (which are normally skipped)
- disjoint_interrupt_policy policy;
- rescale_policy_type robust_policy;
- geometry::get_turns
+ disjoint_interrupt_policy interrupt_policy;
+ dispatch::get_turns
<
- reverse1, reverse2,
- assign_disjoint_policy
- >(geometry1, geometry2, robust_policy, turns, policy);
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type,
+ Geometry1,
+ Geometry2,
+ overlay::do_reverse<geometry::point_order<Geometry1>::value>::value, // should be false
+ overlay::do_reverse<geometry::point_order<Geometry2>::value>::value, // should be false
+ detail::get_turns::get_turn_info_type
+ <
+ Geometry1, Geometry2, assign_disjoint_policy
+ >
+ >::apply(0, geometry1, 1, geometry2,
+ rescale_policy_type(), turns, interrupt_policy);
- return !policy.has_intersections;
+ return !interrupt_policy.has_intersections;
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp
index d181726e2e..8d82f7c911 100644
--- a/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp
@@ -32,6 +32,7 @@
#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
@@ -44,34 +45,6 @@ namespace detail { namespace disjoint
{
-template <typename MultiRange, typename SegmentOrBox>
-struct disjoint_multirange_segment_or_box
-{
- static inline
- bool apply(MultiRange const& multirange, SegmentOrBox const& segment_or_box)
- {
- typedef typename boost::range_iterator
- <
- MultiRange const
- >::type const_iterator;
-
- for (const_iterator it = boost::begin(multirange);
- it != boost::end(multirange); ++it)
- {
- if ( !dispatch::disjoint
- <
- typename boost::range_value<MultiRange>::type,
- SegmentOrBox
- >::apply(*it, segment_or_box) )
- {
- return false;
- }
- }
- return true;
- }
-};
-
-
template
<
typename Range,
@@ -160,7 +133,7 @@ template <typename MultiLinestring, typename SegmentOrBox>
struct disjoint_linear_segment_or_box
<
MultiLinestring, SegmentOrBox, multi_linestring_tag
- > : disjoint_multirange_segment_or_box<MultiLinestring, SegmentOrBox>
+ > : multirange_constant_size_geometry<MultiLinestring, SegmentOrBox>
{};
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
new file mode 100644
index 0000000000..29e438e546
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
@@ -0,0 +1,286 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP
+
+#include <algorithm>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+
+#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/relate/less.hpp>
+
+#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace disjoint
+{
+
+
+template <typename MultiPoint1, typename MultiPoint2>
+class multipoint_multipoint
+{
+private:
+ template <typename Iterator>
+ class unary_disjoint_predicate
+ : detail::relate::less
+ {
+ private:
+ typedef detail::relate::less base_type;
+
+ public:
+ unary_disjoint_predicate(Iterator first, Iterator last)
+ : base_type(), m_first(first), m_last(last)
+ {}
+
+ template <typename Point>
+ inline bool apply(Point const& point) const
+ {
+ return !std::binary_search(m_first,
+ m_last,
+ point,
+ static_cast<base_type const&>(*this));
+ }
+
+ private:
+ Iterator m_first, m_last;
+ };
+
+public:
+ static inline bool apply(MultiPoint1 const& multipoint1,
+ MultiPoint2 const& multipoint2)
+ {
+ BOOST_GEOMETRY_ASSERT( boost::size(multipoint1) <= boost::size(multipoint2) );
+
+ typedef typename boost::range_value<MultiPoint1>::type point1_type;
+
+ std::vector<point1_type> points1(boost::begin(multipoint1),
+ boost::end(multipoint1));
+
+ std::sort(points1.begin(), points1.end(), detail::relate::less());
+
+ typedef unary_disjoint_predicate
+ <
+ typename std::vector<point1_type>::const_iterator
+ > predicate_type;
+
+ return check_iterator_range
+ <
+ predicate_type
+ >::apply(boost::begin(multipoint2),
+ boost::end(multipoint2),
+ predicate_type(points1.begin(), points1.end()));
+ }
+};
+
+
+template <typename MultiPoint, typename Linear>
+class multipoint_linear
+{
+private:
+ // structs for partition -- start
+ struct expand_box
+ {
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& total, Geometry const& geometry)
+ {
+ geometry::expand(total, geometry::return_envelope<Box>(geometry));
+ }
+
+ };
+
+ struct overlaps_box
+ {
+ template <typename Box, typename Geometry>
+ static inline bool apply(Box const& box, Geometry const& geometry)
+ {
+ return ! dispatch::disjoint<Geometry, Box>::apply(geometry, box);
+ }
+ };
+
+ class item_visitor_type
+ {
+ public:
+ item_visitor_type() : m_intersection_found(false) {}
+
+ template <typename Item1, typename Item2>
+ inline void apply(Item1 const& item1, Item2 const& item2)
+ {
+ if (! m_intersection_found
+ && ! dispatch::disjoint<Item1, Item2>::apply(item1, item2))
+ {
+ m_intersection_found = true;
+ }
+ }
+
+ inline bool intersection_found() const { return m_intersection_found; }
+
+ private:
+ bool m_intersection_found;
+ };
+ // structs for partition -- end
+
+ class segment_range
+ {
+ public:
+ typedef geometry::segment_iterator<Linear const> const_iterator;
+ typedef const_iterator iterator;
+
+ segment_range(Linear const& linear)
+ : m_linear(linear)
+ {}
+
+ const_iterator begin() const
+ {
+ return geometry::segments_begin(m_linear);
+ }
+
+ const_iterator end() const
+ {
+ return geometry::segments_end(m_linear);
+ }
+
+ private:
+ Linear const& m_linear;
+ };
+
+public:
+ static inline bool apply(MultiPoint const& multipoint, Linear const& linear)
+ {
+ item_visitor_type visitor;
+
+ geometry::partition
+ <
+ geometry::model::box<typename point_type<MultiPoint>::type>,
+ expand_box,
+ overlaps_box
+ >::apply(multipoint, segment_range(linear), visitor);
+
+ return ! visitor.intersection_found();
+ }
+
+ static inline bool apply(Linear const& linear, MultiPoint const& multipoint)
+ {
+ return apply(multipoint, linear);
+ }
+};
+
+
+}} // namespace detail::disjoint
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Point, typename MultiPoint, std::size_t DimensionCount>
+struct disjoint
+ <
+ Point, MultiPoint, DimensionCount, point_tag, multi_point_tag, false
+ > : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Point>
+{};
+
+
+template <typename MultiPoint, typename Segment, std::size_t DimensionCount>
+struct disjoint
+ <
+ MultiPoint, Segment, DimensionCount, multi_point_tag, segment_tag, false
+ > : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Segment>
+{};
+
+
+template <typename MultiPoint, typename Box, std::size_t DimensionCount>
+struct disjoint
+ <
+ MultiPoint, Box, DimensionCount, multi_point_tag, box_tag, false
+ > : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Box>
+{};
+
+
+template
+<
+ typename MultiPoint1,
+ typename MultiPoint2,
+ std::size_t DimensionCount
+>
+struct disjoint
+ <
+ MultiPoint1, MultiPoint2, DimensionCount,
+ multi_point_tag, multi_point_tag, false
+ >
+{
+ static inline bool apply(MultiPoint1 const& multipoint1,
+ MultiPoint2 const& multipoint2)
+ {
+ if ( boost::size(multipoint2) < boost::size(multipoint1) )
+ {
+ return detail::disjoint::multipoint_multipoint
+ <
+ MultiPoint2, MultiPoint1
+ >::apply(multipoint2, multipoint1);
+ }
+
+ return detail::disjoint::multipoint_multipoint
+ <
+ MultiPoint1, MultiPoint2
+ >::apply(multipoint1, multipoint2);
+ }
+};
+
+
+template <typename Linear, typename MultiPoint, std::size_t DimensionCount>
+struct disjoint
+ <
+ Linear, MultiPoint, DimensionCount, linear_tag, multi_point_tag, false
+ > : detail::disjoint::multipoint_linear<MultiPoint, Linear>
+{};
+
+
+template <typename MultiPoint, typename Linear, std::size_t DimensionCount>
+struct disjoint
+ <
+ MultiPoint, Linear, DimensionCount, multi_point_tag, linear_tag, false
+ > : detail::disjoint::multipoint_linear<MultiPoint, Linear>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp
new file mode 100644
index 0000000000..78a683e46e
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp
@@ -0,0 +1,85 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIRANGE_GEOMETRY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIRANGE_GEOMETRY_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace disjoint
+{
+
+
+template <typename Geometry, typename BinaryPredicate>
+class unary_disjoint_geometry_to_query_geometry
+{
+public:
+ unary_disjoint_geometry_to_query_geometry(Geometry const& geometry)
+ : m_geometry(geometry)
+ {}
+
+ template <typename QueryGeometry>
+ inline bool apply(QueryGeometry const& query_geometry) const
+ {
+ return BinaryPredicate::apply(query_geometry, m_geometry);
+ }
+
+private:
+ Geometry const& m_geometry;
+};
+
+
+template<typename MultiRange, typename ConstantSizeGeometry>
+struct multirange_constant_size_geometry
+{
+ static inline bool apply(MultiRange const& multirange,
+ ConstantSizeGeometry const& constant_size_geometry)
+ {
+ typedef unary_disjoint_geometry_to_query_geometry
+ <
+ ConstantSizeGeometry,
+ dispatch::disjoint
+ <
+ typename boost::range_value<MultiRange>::type,
+ ConstantSizeGeometry
+ >
+ > unary_predicate_type;
+
+ return detail::check_iterator_range
+ <
+ unary_predicate_type
+ >::apply(boost::begin(multirange), boost::end(multirange),
+ unary_predicate_type(constant_size_geometry));
+ }
+
+ static inline bool apply(ConstantSizeGeometry const& constant_size_geometry,
+ MultiRange const& multirange)
+ {
+ return apply(multirange, constant_size_geometry);
+ }
+};
+
+
+}} // namespace detail::disjoint
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIRANGE_GEOMETRY_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/point_box.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/point_box.hpp
index ea6609a153..12213db056 100644
--- a/3party/boost/boost/geometry/algorithms/detail/disjoint/point_box.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/point_box.hpp
@@ -70,8 +70,21 @@ struct point_box<Point, Box, DimensionCount, DimensionCount>
}
};
+/*!
+ \brief Internal utility function to detect if point/box are disjoint
+ */
+template <typename Point, typename Box>
+inline bool disjoint_point_box(Point const& point, Box const& box)
+{
+ return detail::disjoint::point_box
+ <
+ Point, Box,
+ 0, dimension<Point>::type::value
+ >::apply(point, box);
+}
+
-}} // namespace detail::equals
+}} // namespace detail::disjoint
#endif // DOXYGEN_NO_DETAIL
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
index a58bff41da..9ae43f73d0 100644
--- a/3party/boost/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
@@ -1,12 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -21,8 +21,6 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_GEOMETRY_HPP
-#include <boost/geometry/geometries/segment.hpp>
-
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
@@ -39,24 +37,13 @@ namespace detail { namespace disjoint
{
-template<typename Point, typename Geometry>
-struct disjoint_point_linear
-{
- static inline
- bool apply(Point const& pt, Geometry const& g)
- {
- return !geometry::covered_by(pt, g);
- }
-};
-
-
-template <typename Geometry1, typename Geometry2>
struct reverse_covered_by
{
+ template <typename Geometry1, typename Geometry2>
static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
- return !geometry::covered_by(geometry1, geometry2);
+ return ! geometry::covered_by(geometry1, geometry2);
}
};
@@ -74,30 +61,20 @@ namespace dispatch
template<typename Point, typename Linear, std::size_t DimensionCount>
struct disjoint<Point, Linear, DimensionCount, point_tag, linear_tag, false>
- : public detail::disjoint::disjoint_point_linear<Point, Linear>
+ : detail::disjoint::reverse_covered_by
{};
template <typename Point, typename Areal, std::size_t DimensionCount>
struct disjoint<Point, Areal, DimensionCount, point_tag, areal_tag, false>
- : detail::disjoint::reverse_covered_by<Point, Areal>
+ : detail::disjoint::reverse_covered_by
{};
template<typename Point, typename Segment, std::size_t DimensionCount>
struct disjoint<Point, Segment, DimensionCount, point_tag, segment_tag, false>
-{
- static inline bool apply(Point const& point, Segment const& segment)
- {
- typedef geometry::model::referring_segment<Point const> other_segment;
-
- other_segment other(point, point);
- return detail::disjoint::disjoint_segment
- <
- Segment, other_segment
- >::apply(segment, other);
- }
-};
+ : detail::disjoint::reverse_covered_by
+{};
} // namespace dispatch
diff --git a/3party/boost/boost/geometry/algorithms/detail/disjoint/point_point.hpp b/3party/boost/boost/geometry/algorithms/detail/disjoint/point_point.hpp
index b1d32bf95e..7580b7287b 100644
--- a/3party/boost/boost/geometry/algorithms/detail/disjoint/point_point.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/disjoint/point_point.hpp
@@ -1,12 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -23,11 +23,26 @@
#include <cstddef>
+#include <boost/type_traits/is_same.hpp>
+
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_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/cs.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/algorithms/transform.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
@@ -40,38 +55,146 @@ namespace boost { namespace geometry
namespace detail { namespace disjoint
{
-template
-<
- typename Point1, typename Point2,
- std::size_t Dimension, std::size_t DimensionCount
->
-struct point_point
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct point_point_generic
{
+ template <typename Point1, typename Point2>
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);
+ return
+ point_point_generic<Dimension + 1, DimensionCount>::apply(p1, p2);
}
};
-
-template <typename Point1, typename Point2, std::size_t DimensionCount>
-struct point_point<Point1, Point2, DimensionCount, DimensionCount>
+template <std::size_t DimensionCount>
+struct point_point_generic<DimensionCount, DimensionCount>
{
- static inline bool apply(Point1 const& , Point2 const& )
+ template <typename Point1, typename Point2>
+ static inline bool apply(Point1 const&, Point2 const&)
{
return false;
}
};
+class point_point_on_spheroid
+{
+private:
+ template <typename Point1, typename Point2, bool SameUnits>
+ struct are_same_points
+ {
+ static inline bool apply(Point1 const& point1, Point2 const& point2)
+ {
+ typedef typename helper_geometry<Point1>::type helper_point_type1;
+ typedef typename helper_geometry<Point2>::type helper_point_type2;
+
+ helper_point_type1 point1_normalized
+ = return_normalized<helper_point_type1>(point1);
+ helper_point_type2 point2_normalized
+ = return_normalized<helper_point_type2>(point2);
+
+ return point_point_generic
+ <
+ 0, dimension<Point1>::value
+ >::apply(point1_normalized, point2_normalized);
+ }
+ };
+
+ template <typename Point1, typename Point2>
+ struct are_same_points<Point1, Point2, false> // points have different units
+ {
+ static inline bool apply(Point1 const& point1, Point2 const& point2)
+ {
+ typedef typename geometry::select_most_precise
+ <
+ typename fp_coordinate_type<Point1>::type,
+ typename fp_coordinate_type<Point2>::type
+ >::type calculation_type;
+
+ typename helper_geometry
+ <
+ Point1, calculation_type, radian
+ >::type helper_point1, helper_point2;
+
+ Point1 point1_normalized = return_normalized<Point1>(point1);
+ Point2 point2_normalized = return_normalized<Point2>(point2);
+
+ geometry::transform(point1_normalized, helper_point1);
+ geometry::transform(point2_normalized, helper_point2);
+
+ return point_point_generic
+ <
+ 0, dimension<Point1>::value
+ >::apply(helper_point1, helper_point2);
+ }
+ };
+
+public:
+ template <typename Point1, typename Point2>
+ static inline bool apply(Point1 const& point1, Point2 const& point2)
+ {
+ return are_same_points
+ <
+ Point1,
+ Point2,
+ boost::is_same
+ <
+ typename coordinate_system<Point1>::type::units,
+ typename coordinate_system<Point2>::type::units
+ >::value
+ >::apply(point1, point2);
+ }
+};
+
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount,
+ typename CSTag1 = typename cs_tag<Point1>::type,
+ typename CSTag2 = CSTag1
+>
+struct point_point
+ : point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag>
+{};
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point
+ <
+ Point1, Point2, Dimension, DimensionCount, spherical_equatorial_tag
+ > : point_point_on_spheroid
+{};
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point
+ <
+ Point1, Point2, Dimension, DimensionCount, geographic_tag
+ > : point_point_on_spheroid
+{};
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag>
+ : point_point_generic<Dimension, DimensionCount>
+{};
+
+
/*!
\brief Internal utility function to detect of points are disjoint
\note To avoid circular references
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/backward_compatibility.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/backward_compatibility.hpp
index 363439d20c..5b49e571dd 100644
--- a/3party/boost/boost/geometry/algorithms/detail/distance/backward_compatibility.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/backward_compatibility.hpp
@@ -20,8 +20,6 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BACKWARD_COMPATIBILITY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BACKWARD_COMPATIBILITY_HPP
-#include <utility>
-
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -35,8 +33,7 @@
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
-#include <boost/geometry/algorithms/detail/distance/single_to_multi.hpp>
-#include <boost/geometry/algorithms/detail/distance/multi_to_multi.hpp>
+#include <boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp>
namespace boost { namespace geometry
@@ -106,7 +103,10 @@ struct distance
>
{
- static inline typename return_type<Strategy, Point, typename point_type<Linestring>::type>::type
+ static inline typename strategy::distance::services::return_type
+ <
+ Strategy, Point, typename point_type<Linestring>::type
+ >::type
apply(Point const& point,
Linestring const& linestring,
Strategy const&)
@@ -151,15 +151,12 @@ struct distance
Strategy
>::type ps_strategy_type;
- std::pair<return_type, bool>
- dc = detail::distance::point_to_ring
+ return detail::distance::point_to_ring
<
Point, Ring,
geometry::closure<Ring>::value,
ps_strategy_type
>::apply(point, ring, ps_strategy_type());
-
- return dc.second ? return_type(0) : dc.first;
}
};
@@ -179,8 +176,8 @@ struct distance
>::type return_type;
static inline return_type apply(Point const& point,
- Polygon const& polygon,
- Strategy const&)
+ Polygon const& polygon,
+ Strategy const&)
{
typedef typename detail::distance::default_ps_strategy
<
@@ -189,25 +186,19 @@ struct distance
Strategy
>::type ps_strategy_type;
- std::pair<return_type, bool>
- dc = detail::distance::point_to_polygon
+ return detail::distance::point_to_polygon
<
- Point, Polygon,
+ Point,
+ Polygon,
geometry::closure<Polygon>::value,
ps_strategy_type
>::apply(point, polygon, ps_strategy_type());
-
- return dc.second ? return_type(0) : dc.first;
}
};
-namespace splitted_dispatch
-{
-
-
template
<
typename Point,
@@ -215,11 +206,11 @@ template
typename MultiGeometryTag,
typename Strategy
>
-struct distance_single_to_multi
+struct distance
<
Point, MultiGeometry, Strategy,
point_tag, MultiGeometryTag,
- strategy_tag_distance_point_point
+ strategy_tag_distance_point_point, false
>
{
typedef typename strategy::distance::services::return_type
@@ -238,11 +229,11 @@ struct distance_single_to_multi
Strategy
>::type ps_strategy_type;
- return distance_single_to_multi
+ return distance
<
Point, MultiGeometry, ps_strategy_type,
point_tag, MultiGeometryTag,
- strategy_tag_distance_point_segment
+ strategy_tag_distance_point_segment, false
>::apply(point, multigeometry, ps_strategy_type());
}
};
@@ -255,11 +246,11 @@ template
typename GeometryTag,
typename Strategy
>
-struct distance_single_to_multi
+struct distance
<
Geometry, MultiPoint, Strategy,
GeometryTag, multi_point_tag,
- strategy_tag_distance_point_point
+ strategy_tag_distance_point_point, false
>
{
typedef typename strategy::distance::services::return_type
@@ -280,11 +271,11 @@ struct distance_single_to_multi
Strategy
>::type ps_strategy_type;
- return distance_single_to_multi
+ return distance
<
Geometry, MultiPoint, ps_strategy_type,
GeometryTag, multi_point_tag,
- strategy_tag_distance_point_segment
+ strategy_tag_distance_point_segment, false
>::apply(geometry, multipoint, ps_strategy_type());
}
};
@@ -297,11 +288,11 @@ template
typename MultiGeometryTag,
typename Strategy
>
-struct distance_multi_to_multi
+struct distance
<
MultiPoint, MultiGeometry, Strategy,
multi_point_tag, MultiGeometryTag,
- strategy_tag_distance_point_point
+ strategy_tag_distance_point_point, false
>
{
typedef typename strategy::distance::services::return_type
@@ -322,19 +313,16 @@ struct distance_multi_to_multi
Strategy
>::type ps_strategy_type;
- return distance_multi_to_multi
+ return distance
<
MultiPoint, MultiGeometry, ps_strategy_type,
multi_point_tag, MultiGeometryTag,
- strategy_tag_distance_point_segment
+ strategy_tag_distance_point_segment, false
>::apply(multipoint, multigeometry, ps_strategy_type());
}
};
-} // namespace splitted_dispatch
-
-
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/box_to_box.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/box_to_box.hpp
index 57c908d38f..44778e9e06 100644
--- a/3party/boost/boost/geometry/algorithms/detail/distance/box_to_box.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/box_to_box.hpp
@@ -10,6 +10,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BOX_TO_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BOX_TO_BOX_HPP
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -42,7 +44,7 @@ struct distance
>::type
apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
{
- boost::ignore_unused_variable_warning(strategy);
+ boost::ignore_unused(strategy);
return strategy.apply(box1, box2);
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/default_strategies.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/default_strategies.hpp
index 3b79f82a36..a01ace2b58 100644
--- a/3party/boost/boost/geometry/algorithms/detail/distance/default_strategies.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/default_strategies.hpp
@@ -95,10 +95,7 @@ struct default_strategy<Pointlike, Box, pointlike_tag, box_tag, false>
<
point_tag, box_tag,
typename point_type<Pointlike>::type,
- typename point_type<Box>::type,
- cartesian_tag,
- cartesian_tag,
- void
+ typename point_type<Box>::type
>
{};
@@ -109,10 +106,7 @@ struct default_strategy<Box1, Box2, box_tag, box_tag, false>
<
box_tag, box_tag,
typename point_type<Box1>::type,
- typename point_type<Box2>::type,
- cartesian_tag,
- cartesian_tag,
- void
+ typename point_type<Box2>::type
>
{};
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp
deleted file mode 100644
index 7ebb394665..0000000000
--- a/3party/boost/boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp
+++ /dev/null
@@ -1,383 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2014, Oracle and/or its affiliates.
-
-// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
-
-// Licensed under the Boost Software License version 1.0.
-// http://www.boost.org/users/license.html
-
-#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_GEOMETRY_RTREE_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_GEOMETRY_RTREE_HPP
-
-#include <cstddef>
-#include <algorithm>
-#include <iterator>
-
-#include <boost/assert.hpp>
-#include <boost/range.hpp>
-
-#include <boost/geometry/core/tag.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/iterators/point_iterator.hpp>
-#include <boost/geometry/iterators/has_one_element.hpp>
-
-#include <boost/geometry/algorithms/for_each.hpp>
-#include <boost/geometry/algorithms/intersects.hpp>
-
-#include <boost/geometry/strategies/distance.hpp>
-#include <boost/geometry/strategies/distance_comparable_to_regular.hpp>
-#include <boost/geometry/strategies/tags.hpp>
-
-#include <boost/geometry/algorithms/dispatch/distance.hpp>
-
-#include <boost/geometry/index/rtree.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace distance
-{
-
-
-
-template
-<
- typename RTreePoint,
- typename Geometry,
- typename Strategy
->
-class point_range_to_geometry_rtree
-{
-private:
- typedef typename strategy::distance::services::comparable_type
- <
- Strategy
- >::type comparable_strategy;
-
- typedef typename strategy::distance::services::return_type
- <
- comparable_strategy,
- RTreePoint,
- typename point_type<Geometry>::type
- >::type comparable_return_type;
-
- typedef index::rtree<RTreePoint, index::linear<8> > r_tree;
-
- // functor to evaluate minimum comparable distance
- struct minimum_comparable_distance_evaluator
- {
- r_tree const& m_r_tree;
- comparable_strategy const& m_cstrategy;
- bool m_first;
- comparable_return_type m_min_cd;
-
- minimum_comparable_distance_evaluator
- (r_tree const& r_tree, comparable_strategy const& cstrategy)
- : m_r_tree(r_tree)
- , m_cstrategy(cstrategy)
- , m_first(true)
- , m_min_cd()
- {}
-
- template <typename QueryGeometry>
- inline void operator()(QueryGeometry const& query_geometry)
- {
- typename r_tree::value_type t_v;
- std::size_t n =
- m_r_tree.query(index::nearest(query_geometry, 1), &t_v);
-
- BOOST_ASSERT( n > 0 );
-
- comparable_return_type cd = dispatch::distance
- <
- typename r_tree::value_type,
- QueryGeometry,
- comparable_strategy
- >::apply(t_v, query_geometry, m_cstrategy);
-
- if ( m_first || cd < m_min_cd )
- {
- m_first = false;
- m_min_cd = cd;
- }
- }
- };
-
-
-
- // class to choose between for_each_point and for_each_segment
- template <typename G, typename Tag = typename tag<G>::type>
- struct for_each_selector
- {
- typedef dispatch::for_each_segment<G> type;
- };
-
- template <typename MultiPoint>
- struct for_each_selector<MultiPoint, multi_point_tag>
- {
- typedef dispatch::for_each_point<MultiPoint> type;
- };
-
-public:
- typedef typename strategy::distance::services::return_type
- <
- Strategy,
- RTreePoint,
- typename point_type<Geometry>::type
- >::type return_type;
-
- template <typename PointIterator>
- static inline return_type apply(PointIterator points_first,
- PointIterator points_beyond,
- Geometry const& geometry,
- Strategy const& strategy)
- {
- BOOST_ASSERT( points_first != points_beyond );
-
- if ( geometry::has_one_element(points_first, points_beyond) )
- {
- return dispatch::distance
- <
- typename std::iterator_traits<PointIterator>::value_type,
- Geometry,
- Strategy
- >::apply(*points_first, geometry, strategy);
- }
-
- // create -- packing algorithm
- r_tree rt(points_first, points_beyond);
-
- minimum_comparable_distance_evaluator
- functor(rt,
- strategy::distance::services::get_comparable
- <
- Strategy
- >::apply(strategy));
-
- for_each_selector<Geometry>::type::apply(geometry, functor);
-
- return strategy::distance::services::comparable_to_regular
- <
- comparable_strategy, Strategy, RTreePoint, Geometry
- >::apply(functor.m_min_cd);
- }
-};
-
-
-
-template
-<
- typename Geometry1,
- typename Geometry2,
- typename Strategy
->
-class geometry_to_geometry_rtree
-{
- // the following works with linear geometries seen as ranges of points
- //
- // we compute the r-tree for the points of one range and then,
- // compute nearest points for the segments of the other,
- // ... and ...
- // vice versa.
-
-private:
- typedef typename strategy::distance::services::comparable_type
- <
- Strategy
- >::type comparable_strategy;
-
- typedef typename strategy::distance::services::return_type
- <
- comparable_strategy,
- typename point_type<Geometry1>::type,
- typename point_type<Geometry2>::type
- >::type comparable_return_type;
-
-public:
- typedef typename strategy::distance::services::return_type
- <
- Strategy,
- typename point_type<Geometry1>::type,
- typename point_type<Geometry2>::type
- >::type return_type;
-
- static inline return_type apply(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- Strategy const& strategy,
- bool check_intersection = true)
- {
- point_iterator<Geometry1 const> first1 = points_begin(geometry1);
- point_iterator<Geometry1 const> beyond1 = points_end(geometry1);
- point_iterator<Geometry2 const> first2 = points_begin(geometry2);
- point_iterator<Geometry2 const> beyond2 = points_end(geometry2);
-
- if ( geometry::has_one_element(first1, beyond1) )
- {
- return dispatch::distance
- <
- typename point_type<Geometry1>::type,
- Geometry2,
- Strategy
- >::apply(*first1, geometry2, strategy);
- }
-
- if ( geometry::has_one_element(first2, beyond2) )
- {
- return dispatch::distance
- <
- typename point_type<Geometry2>::type,
- Geometry1,
- Strategy
- >::apply(*first2, geometry1, strategy);
- }
-
- if ( check_intersection && geometry::intersects(geometry1, geometry2) )
- {
- return return_type(0);
- }
-
- comparable_strategy cstrategy =
- strategy::distance::services::get_comparable
- <
- Strategy
- >::apply(strategy);
-
- comparable_return_type cdist1 = point_range_to_geometry_rtree
- <
- typename point_type<Geometry1>::type,
- Geometry2,
- comparable_strategy
- >::apply(first1, beyond1, geometry2, cstrategy);
-
- comparable_return_type cdist2 = point_range_to_geometry_rtree
- <
- typename point_type<Geometry2>::type,
- Geometry1,
- comparable_strategy
- >::apply(first2, beyond2, geometry1, cstrategy);
-
-
- return strategy::distance::services::comparable_to_regular
- <
- comparable_strategy, Strategy, Geometry1, Geometry2
- >::apply( (std::min)(cdist1, cdist2) );
- }
-};
-
-
-
-
-}} // namespace detail::distance
-#endif // DOXYGEN_NO_DETAIL
-
-
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-template <typename Linestring1, typename Linestring2, typename Strategy>
-struct distance
- <
- Linestring1, Linestring2, Strategy,
- linestring_tag, linestring_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::geometry_to_geometry_rtree
- <
- Linestring1, Linestring2, Strategy
- >
-{};
-
-
-
-template <typename Linestring, typename Polygon, typename Strategy>
-struct distance
- <
- Linestring, Polygon, Strategy,
- linestring_tag, polygon_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::geometry_to_geometry_rtree
- <
- Linestring, Polygon, Strategy
- >
-{};
-
-
-
-template <typename Linestring, typename Ring, typename Strategy>
-struct distance
- <
- Linestring, Ring, Strategy,
- linestring_tag, ring_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::geometry_to_geometry_rtree
- <
- Linestring, Ring, Strategy
- >
-{};
-
-
-
-template <typename Polygon1, typename Polygon2, typename Strategy>
-struct distance
- <
- Polygon1, Polygon2, Strategy,
- polygon_tag, polygon_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::geometry_to_geometry_rtree
- <
- Polygon1, Polygon2, Strategy
- >
-{};
-
-
-
-template <typename Polygon, typename Ring, typename Strategy>
-struct distance
- <
- Polygon, Ring, Strategy,
- polygon_tag, ring_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::geometry_to_geometry_rtree
- <
- Polygon, Ring, Strategy
- >
-{};
-
-
-
-template <typename Ring1, typename Ring2, typename Strategy>
-struct distance
- <
- Ring1, Ring2, Strategy,
- ring_tag, ring_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::geometry_to_geometry_rtree
- <
- Ring1, Ring2, Strategy
- >
-{};
-
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_GEOMETRY_RTREE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp
new file mode 100644
index 0000000000..d6de7cac91
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp
@@ -0,0 +1,464 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_SEGMENT_OR_BOX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_SEGMENT_OR_BOX_HPP
+
+#include <iterator>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+
+#include <boost/geometry/iterators/point_iterator.hpp>
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/dispatch/distance.hpp>
+
+#include <boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp>
+#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
+
+#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
+
+#include <boost/geometry/util/condition.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance
+{
+
+
+// closure of segment or box point range
+template
+<
+ typename SegmentOrBox,
+ typename Tag = typename tag<SegmentOrBox>::type
+>
+struct segment_or_box_point_range_closure
+ : not_implemented<SegmentOrBox>
+{};
+
+template <typename Segment>
+struct segment_or_box_point_range_closure<Segment, segment_tag>
+{
+ static const closure_selector value = closed;
+};
+
+template <typename Box>
+struct segment_or_box_point_range_closure<Box, box_tag>
+{
+ static const closure_selector value = open;
+};
+
+
+
+template
+<
+ typename Geometry,
+ typename SegmentOrBox,
+ typename Strategy,
+ typename Tag = typename tag<Geometry>::type
+>
+class geometry_to_segment_or_box
+{
+private:
+ typedef typename point_type<SegmentOrBox>::type segment_or_box_point;
+
+ typedef typename strategy::distance::services::comparable_type
+ <
+ Strategy
+ >::type comparable_strategy;
+
+ typedef detail::closest_feature::point_to_point_range
+ <
+ typename point_type<Geometry>::type,
+ std::vector<segment_or_box_point>,
+ segment_or_box_point_range_closure<SegmentOrBox>::value,
+ comparable_strategy
+ > point_to_point_range;
+
+ typedef detail::closest_feature::geometry_to_range geometry_to_range;
+
+ typedef typename strategy::distance::services::return_type
+ <
+ comparable_strategy,
+ typename point_type<Geometry>::type,
+ segment_or_box_point
+ >::type comparable_return_type;
+
+
+ // assign the new minimum value for an iterator of the point range
+ // of a segment or a box
+ template
+ <
+ typename SegOrBox,
+ typename SegOrBoxTag = typename tag<SegOrBox>::type
+ >
+ struct assign_new_min_iterator
+ : not_implemented<SegOrBox>
+ {};
+
+ template <typename Segment>
+ struct assign_new_min_iterator<Segment, segment_tag>
+ {
+ template <typename Iterator>
+ static inline void apply(Iterator&, Iterator)
+ {
+ }
+ };
+
+ template <typename Box>
+ struct assign_new_min_iterator<Box, box_tag>
+ {
+ template <typename Iterator>
+ static inline void apply(Iterator& it_min, Iterator it)
+ {
+ it_min = it;
+ }
+ };
+
+
+ // assign the points of a segment or a box to a range
+ template
+ <
+ typename SegOrBox,
+ typename PointRange,
+ typename SegOrBoxTag = typename tag<SegOrBox>::type
+ >
+ struct assign_segment_or_box_points
+ {};
+
+ template <typename Segment, typename PointRange>
+ struct assign_segment_or_box_points<Segment, PointRange, segment_tag>
+ {
+ static inline void apply(Segment const& segment, PointRange& range)
+ {
+ detail::assign_point_from_index<0>(segment, range[0]);
+ detail::assign_point_from_index<1>(segment, range[1]);
+ }
+ };
+
+ template <typename Box, typename PointRange>
+ struct assign_segment_or_box_points<Box, PointRange, box_tag>
+ {
+ static inline void apply(Box const& box, PointRange& range)
+ {
+ detail::assign_box_corners_oriented<true>(box, range);
+ }
+ };
+
+
+public:
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<Geometry>::type,
+ segment_or_box_point
+ >::type return_type;
+
+ static inline return_type apply(Geometry const& geometry,
+ SegmentOrBox const& segment_or_box,
+ Strategy const& strategy,
+ bool check_intersection = true)
+ {
+ typedef geometry::point_iterator<Geometry const> point_iterator_type;
+ typedef geometry::segment_iterator
+ <
+ Geometry const
+ > segment_iterator_type;
+
+ typedef typename boost::range_const_iterator
+ <
+ std::vector<segment_or_box_point>
+ >::type seg_or_box_const_iterator;
+
+ typedef assign_new_min_iterator<SegmentOrBox> assign_new_value;
+
+
+ if (check_intersection
+ && geometry::intersects(geometry, segment_or_box))
+ {
+ return 0;
+ }
+
+ comparable_strategy cstrategy =
+ strategy::distance::services::get_comparable
+ <
+ Strategy
+ >::apply(strategy);
+
+ // get all points of the segment or the box
+ std::vector<segment_or_box_point>
+ seg_or_box_points(geometry::num_points(segment_or_box));
+
+ assign_segment_or_box_points
+ <
+ SegmentOrBox,
+ std::vector<segment_or_box_point>
+ >::apply(segment_or_box, seg_or_box_points);
+
+ // consider all distances of the points in the geometry to the
+ // segment or box
+ comparable_return_type cd_min1(0);
+ point_iterator_type pit_min;
+ seg_or_box_const_iterator it_min1 = boost::const_begin(seg_or_box_points);
+ seg_or_box_const_iterator it_min2 = it_min1;
+ ++it_min2;
+ bool first = true;
+
+ for (point_iterator_type pit = points_begin(geometry);
+ pit != points_end(geometry); ++pit, first = false)
+ {
+ comparable_return_type cd;
+ std::pair
+ <
+ seg_or_box_const_iterator, seg_or_box_const_iterator
+ > it_pair
+ = point_to_point_range::apply(*pit,
+ boost::const_begin(seg_or_box_points),
+ boost::const_end(seg_or_box_points),
+ cstrategy,
+ cd);
+
+ if (first || cd < cd_min1)
+ {
+ cd_min1 = cd;
+ pit_min = pit;
+ assign_new_value::apply(it_min1, it_pair.first);
+ assign_new_value::apply(it_min2, it_pair.second);
+ }
+ }
+
+ // consider all distances of the points in the segment or box to the
+ // segments of the geometry
+ comparable_return_type cd_min2(0);
+ segment_iterator_type sit_min;
+ seg_or_box_const_iterator it_min;
+
+ first = true;
+ for (seg_or_box_const_iterator it = boost::const_begin(seg_or_box_points);
+ it != boost::const_end(seg_or_box_points); ++it, first = false)
+ {
+ comparable_return_type cd;
+ segment_iterator_type sit
+ = geometry_to_range::apply(*it,
+ segments_begin(geometry),
+ segments_end(geometry),
+ cstrategy,
+ cd);
+
+ if (first || cd < cd_min2)
+ {
+ cd_min2 = cd;
+ it_min = it;
+ sit_min = sit;
+ }
+ }
+
+ if (BOOST_GEOMETRY_CONDITION(is_comparable<Strategy>::value))
+ {
+ return (std::min)(cd_min1, cd_min2);
+ }
+
+ if (cd_min1 < cd_min2)
+ {
+ return strategy.apply(*pit_min, *it_min1, *it_min2);
+ }
+ else
+ {
+ return dispatch::distance
+ <
+ segment_or_box_point,
+ typename std::iterator_traits
+ <
+ segment_iterator_type
+ >::value_type,
+ Strategy
+ >::apply(*it_min, *sit_min, strategy);
+ }
+ }
+
+
+ static inline return_type
+ apply(SegmentOrBox const& segment_or_box, Geometry const& geometry,
+ Strategy const& strategy, bool check_intersection = true)
+ {
+ return apply(geometry, segment_or_box, strategy, check_intersection);
+ }
+};
+
+
+
+template <typename MultiPoint, typename SegmentOrBox, typename Strategy>
+class geometry_to_segment_or_box
+ <
+ MultiPoint, SegmentOrBox, Strategy, multi_point_tag
+ >
+{
+private:
+ typedef detail::closest_feature::geometry_to_range base_type;
+
+ typedef typename boost::range_iterator
+ <
+ MultiPoint const
+ >::type iterator_type;
+
+ typedef detail::closest_feature::geometry_to_range geometry_to_range;
+
+public:
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<SegmentOrBox>::type,
+ typename point_type<MultiPoint>::type
+ >::type return_type;
+
+ static inline return_type apply(MultiPoint const& multipoint,
+ SegmentOrBox const& segment_or_box,
+ Strategy const& strategy)
+ {
+ namespace sds = strategy::distance::services;
+
+ typename sds::return_type
+ <
+ typename sds::comparable_type<Strategy>::type,
+ typename point_type<SegmentOrBox>::type,
+ typename point_type<MultiPoint>::type
+ >::type cd_min;
+
+ iterator_type it_min
+ = geometry_to_range::apply(segment_or_box,
+ boost::begin(multipoint),
+ boost::end(multipoint),
+ sds::get_comparable
+ <
+ Strategy
+ >::apply(strategy),
+ cd_min);
+
+ return
+ is_comparable<Strategy>::value
+ ?
+ cd_min
+ :
+ dispatch::distance
+ <
+ typename point_type<MultiPoint>::type,
+ SegmentOrBox,
+ Strategy
+ >::apply(*it_min, segment_or_box, strategy);
+ }
+};
+
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Linear, typename Segment, typename Strategy>
+struct distance
+ <
+ Linear, Segment, Strategy, linear_tag, segment_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::geometry_to_segment_or_box<Linear, Segment, Strategy>
+{};
+
+
+template <typename Areal, typename Segment, typename Strategy>
+struct distance
+ <
+ Areal, Segment, Strategy, areal_tag, segment_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::geometry_to_segment_or_box<Areal, Segment, Strategy>
+{};
+
+
+template <typename Segment, typename Areal, typename Strategy>
+struct distance
+ <
+ Segment, Areal, Strategy, segment_tag, areal_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::geometry_to_segment_or_box<Areal, Segment, Strategy>
+{};
+
+
+template <typename Linear, typename Box, typename Strategy>
+struct distance
+ <
+ Linear, Box, Strategy, linear_tag, box_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::geometry_to_segment_or_box
+ <
+ Linear, Box, Strategy
+ >
+{};
+
+
+template <typename Areal, typename Box, typename Strategy>
+struct distance
+ <
+ Areal, Box, Strategy, areal_tag, box_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::geometry_to_segment_or_box<Areal, Box, Strategy>
+{};
+
+
+template <typename MultiPoint, typename Segment, typename Strategy>
+struct distance
+ <
+ MultiPoint, Segment, Strategy,
+ multi_point_tag, segment_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::geometry_to_segment_or_box
+ <
+ MultiPoint, Segment, Strategy
+ >
+{};
+
+
+template <typename MultiPoint, typename Box, typename Strategy>
+struct distance
+ <
+ MultiPoint, Box, Strategy,
+ multi_point_tag, box_tag,
+ strategy_tag_distance_point_box, false
+ > : detail::distance::geometry_to_segment_or_box
+ <
+ MultiPoint, Box, Strategy
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_SEGMENT_OR_BOX_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/implementation.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/implementation.hpp
index 45f40bbb33..7c009f4d79 100644
--- a/3party/boost/boost/geometry/algorithms/detail/distance/implementation.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/implementation.hpp
@@ -22,17 +22,14 @@
// the implementation details
#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
-#include <boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp>
+#include <boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp>
+#include <boost/geometry/algorithms/detail/distance/linear_to_linear.hpp>
+#include <boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp>
+#include <boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp>
+#include <boost/geometry/algorithms/detail/distance/segment_to_segment.hpp>
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
-#include <boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp>
#include <boost/geometry/algorithms/detail/distance/box_to_box.hpp>
-#include <boost/geometry/algorithms/detail/distance/single_to_multi.hpp>
-#include <boost/geometry/algorithms/detail/distance/multi_to_multi.hpp>
-#include <boost/geometry/algorithms/detail/distance/multipoint_to_range.hpp>
-#include <boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp>
-#include <boost/geometry/algorithms/detail/distance/segment_to_segment.hpp>
#include <boost/geometry/algorithms/detail/distance/backward_compatibility.hpp>
-
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_IMPLEMENTATION_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/interface.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/interface.hpp
index 9b377f524b..fa8cbd69ee 100644
--- a/3party/boost/boost/geometry/algorithms/detail/distance/interface.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/interface.hpp
@@ -260,13 +260,13 @@ struct distance<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
template
<
- BOOST_VARIANT_ENUM_PARAMS(typename A),
- BOOST_VARIANT_ENUM_PARAMS(typename B)
+ BOOST_VARIANT_ENUM_PARAMS(typename T1),
+ BOOST_VARIANT_ENUM_PARAMS(typename T2)
>
struct distance
<
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(A)>,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(B)>
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
{
template <typename Strategy>
@@ -274,8 +274,8 @@ struct distance
<
typename distance_result
<
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(A)>,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(B)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
Strategy
>::type
>
@@ -304,12 +304,12 @@ struct distance
template <typename Strategy>
static inline typename distance_result
<
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(A)>,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(B)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
Strategy
>::type
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(A)> const& geometry1,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(B)> const& geometry2,
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
return apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/is_comparable.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/is_comparable.hpp
new file mode 100644
index 0000000000..d13cc6c740
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/is_comparable.hpp
@@ -0,0 +1,45 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_IS_COMPARABLE_HPP
+#define BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_IS_COMPARABLE_HPP
+
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance
+{
+
+
+// metafunction to determine is a strategy is comparable or not
+template <typename Strategy>
+struct is_comparable
+ : boost::is_same
+ <
+ Strategy,
+ typename strategy::distance::services::comparable_type
+ <
+ Strategy
+ >::type
+ >
+{};
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_IS_COMPARABLE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/iterator_selector.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/iterator_selector.hpp
new file mode 100644
index 0000000000..363ec465a4
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/iterator_selector.hpp
@@ -0,0 +1,70 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_ITERATOR_SELECTOR_HPP
+#define BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_ITERATOR_SELECTOR_HPP
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/iterators/point_iterator.hpp>
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance
+{
+
+
+// class to choose between point_iterator and segment_iterator
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct iterator_selector
+{
+ typedef geometry::segment_iterator<Geometry> iterator_type;
+
+ static inline iterator_type begin(Geometry& geometry)
+ {
+ return segments_begin(geometry);
+ }
+
+ static inline iterator_type end(Geometry& geometry)
+ {
+ return segments_end(geometry);
+ }
+};
+
+template <typename MultiPoint>
+struct iterator_selector<MultiPoint, multi_point_tag>
+{
+ typedef geometry::point_iterator<MultiPoint> iterator_type;
+
+ static inline iterator_type begin(MultiPoint& multipoint)
+ {
+ return points_begin(multipoint);
+ }
+
+ static inline iterator_type end(MultiPoint& multipoint)
+ {
+ return points_end(multipoint);
+ }
+};
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_ITERATOR_SELECTOR_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp
new file mode 100644
index 0000000000..b63104da7d
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp
@@ -0,0 +1,147 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_OR_AREAL_TO_AREAL_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_OR_AREAL_TO_AREAL_HPP
+
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+#include <boost/geometry/algorithms/intersects.hpp>
+
+#include <boost/geometry/algorithms/detail/distance/linear_to_linear.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance
+{
+
+
+template <typename Linear, typename Areal, typename Strategy>
+struct linear_to_areal
+{
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<Linear>::type,
+ typename point_type<Areal>::type
+ >::type return_type;
+
+ static inline return_type apply(Linear const& linear,
+ Areal const& areal,
+ Strategy const& strategy)
+ {
+ if ( geometry::intersects(linear, areal) )
+ {
+ return 0;
+ }
+
+ return linear_to_linear
+ <
+ Linear, Areal, Strategy
+ >::apply(linear, areal, strategy, false);
+ }
+
+
+ static inline return_type apply(Areal const& areal,
+ Linear const& linear,
+ Strategy const& strategy)
+ {
+ return apply(linear, areal, strategy);
+ }
+};
+
+
+template <typename Areal1, typename Areal2, typename Strategy>
+struct areal_to_areal
+{
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<Areal1>::type,
+ typename point_type<Areal2>::type
+ >::type return_type;
+
+ static inline return_type apply(Areal1 const& areal1,
+ Areal2 const& areal2,
+ Strategy const& strategy)
+ {
+ if ( geometry::intersects(areal1, areal2) )
+ {
+ return 0;
+ }
+
+ return linear_to_linear
+ <
+ Areal1, Areal2, Strategy
+ >::apply(areal1, areal2, strategy, false);
+ }
+};
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Linear, typename Areal, typename Strategy>
+struct distance
+ <
+ Linear, Areal, Strategy,
+ linear_tag, areal_tag,
+ strategy_tag_distance_point_segment, false
+ >
+ : detail::distance::linear_to_areal
+ <
+ Linear, Areal, Strategy
+ >
+{};
+
+
+template <typename Areal, typename Linear, typename Strategy>
+struct distance
+ <
+ Areal, Linear, Strategy,
+ areal_tag, linear_tag,
+ strategy_tag_distance_point_segment, false
+ >
+ : detail::distance::linear_to_areal
+ <
+ Linear, Areal, Strategy
+ >
+{};
+
+
+template <typename Areal1, typename Areal2, typename Strategy>
+struct distance
+ <
+ Areal1, Areal2, Strategy,
+ areal_tag, areal_tag,
+ strategy_tag_distance_point_segment, false
+ >
+ : detail::distance::areal_to_areal
+ <
+ Areal1, Areal2, Strategy
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_OR_AREAL_TO_AREAL_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/linear_to_linear.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/linear_to_linear.hpp
new file mode 100644
index 0000000000..e44b372842
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/linear_to_linear.hpp
@@ -0,0 +1,123 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_LINEAR_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_LINEAR_HPP
+
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+#include <boost/geometry/iterators/point_iterator.hpp>
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/num_segments.hpp>
+
+#include <boost/geometry/algorithms/dispatch/distance.hpp>
+
+#include <boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance
+{
+
+
+template <typename Linear1, typename Linear2, typename Strategy>
+struct linear_to_linear
+{
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<Linear1>::type,
+ typename point_type<Linear2>::type
+ >::type return_type;
+
+ static inline return_type apply(Linear1 const& linear1,
+ Linear2 const& linear2,
+ Strategy const& strategy,
+ bool = false)
+ {
+ if (geometry::num_points(linear1) == 1)
+ {
+ return dispatch::distance
+ <
+ typename point_type<Linear1>::type,
+ Linear2,
+ Strategy
+ >::apply(*points_begin(linear1), linear2, strategy);
+ }
+
+ if (geometry::num_points(linear2) == 1)
+ {
+ return dispatch::distance
+ <
+ typename point_type<Linear2>::type,
+ Linear1,
+ Strategy
+ >::apply(*points_begin(linear2), linear1, strategy);
+ }
+
+ if (geometry::num_segments(linear2) < geometry::num_segments(linear1))
+ {
+ return point_or_segment_range_to_geometry_rtree
+ <
+ geometry::segment_iterator<Linear2 const>,
+ Linear1,
+ Strategy
+ >::apply(geometry::segments_begin(linear2),
+ geometry::segments_end(linear2),
+ linear1,
+ strategy);
+
+ }
+
+ return point_or_segment_range_to_geometry_rtree
+ <
+ geometry::segment_iterator<Linear1 const>,
+ Linear2,
+ Strategy
+ >::apply(geometry::segments_begin(linear1),
+ geometry::segments_end(linear1),
+ linear2,
+ strategy);
+ }
+};
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Linear1, typename Linear2, typename Strategy>
+struct distance
+ <
+ Linear1, Linear2, Strategy,
+ linear_tag, linear_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::linear_to_linear
+ <
+ Linear1, Linear2, Strategy
+ >
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_LINEAR_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp
deleted file mode 100644
index 0d541cc3af..0000000000
--- a/3party/boost/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp
+++ /dev/null
@@ -1,256 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
-
-// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
-
-// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
-// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
-
-// Use, modification and distribution is subject to the Boost Software License,
-// 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_DISTANCE_MULTI_TO_MULTI_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTI_TO_MULTI_HPP
-
-#include <boost/range.hpp>
-
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/tag.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/strategies/distance.hpp>
-#include <boost/geometry/strategies/distance_comparable_to_regular.hpp>
-#include <boost/geometry/strategies/tags.hpp>
-
-#include <boost/geometry/util/math.hpp>
-
-#include <boost/geometry/algorithms/not_implemented.hpp>
-
-#include <boost/geometry/algorithms/dispatch/distance.hpp>
-
-#include <boost/geometry/algorithms/detail/distance/single_to_multi.hpp>
-#include <boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace distance
-{
-
-
-
-template <typename Multi1, typename Multi2, typename Strategy>
-class distance_multi_to_multi_generic
-{
-private:
- typedef typename strategy::distance::services::comparable_type
- <
- Strategy
- >::type comparable_strategy;
-
- typedef typename strategy::distance::services::return_type
- <
- comparable_strategy,
- typename point_type<Multi1>::type,
- typename point_type<Multi2>::type
- >::type comparable_return_type;
-
-public:
- typedef typename strategy::distance::services::return_type
- <
- Strategy,
- typename point_type<Multi1>::type,
- typename point_type<Multi2>::type
- >::type return_type;
-
- static inline return_type apply(Multi1 const& multi1,
- Multi2 const& multi2, Strategy const& strategy)
- {
- comparable_return_type min_cdist = comparable_return_type();
- bool first = true;
-
- comparable_strategy cstrategy =
- strategy::distance::services::get_comparable
- <
- Strategy
- >::apply(strategy);
-
- for(typename range_iterator<Multi1 const>::type it = boost::begin(multi1);
- it != boost::end(multi1);
- ++it, first = false)
- {
- comparable_return_type cdist =
- dispatch::splitted_dispatch::distance_single_to_multi
- <
- typename range_value<Multi1>::type,
- Multi2,
- comparable_strategy,
- typename tag<typename range_value<Multi1>::type>::type,
- typename tag<Multi2>::type,
- typename strategy::distance::services::tag
- <
- comparable_strategy
- >::type
- >::apply(*it, multi2, cstrategy);
- if (first || cdist < min_cdist)
- {
- min_cdist = cdist;
- if ( geometry::math::equals(min_cdist, 0) )
- {
- break;
- }
- }
- }
-
- return strategy::distance::services::comparable_to_regular
- <
- comparable_strategy,
- Strategy,
- Multi1,
- Multi2
- >::apply(min_cdist);
- }
-};
-
-
-}} // namespace detail::distance
-#endif // DOXYGEN_NO_DETAIL
-
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-namespace splitted_dispatch
-{
-
-
-template
-<
- typename MultiGeometry1,
- typename MultiGeometry2,
- typename Strategy,
- typename Tag1,
- typename Tag2,
- typename StrategyTag
->
-struct distance_multi_to_multi
- : not_implemented<MultiGeometry1, MultiGeometry2>
-{};
-
-
-
-template
-<
- typename MultiPoint,
- typename MultiPolygon,
- typename Strategy
->
-struct distance_multi_to_multi
- <
- MultiPoint, MultiPolygon, Strategy,
- multi_point_tag, multi_polygon_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::distance_multi_to_multi_generic
- <
- MultiPoint, MultiPolygon, Strategy
- >
-{};
-
-
-
-template
-<
- typename MultiLinestring1,
- typename MultiLinestring2,
- typename Strategy
->
-struct distance_multi_to_multi
- <
- MultiLinestring1, MultiLinestring2, Strategy,
- multi_linestring_tag, multi_linestring_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- MultiLinestring1, MultiLinestring2, Strategy
- >
-{};
-
-
-template
-<
- typename MultiLinestring,
- typename MultiPolygon,
- typename Strategy
->
-struct distance_multi_to_multi
- <
- MultiLinestring, MultiPolygon, Strategy,
- multi_linestring_tag, multi_polygon_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- MultiLinestring, MultiPolygon, Strategy
- >
-{};
-
-
-template <typename MultiPolygon1, typename MultiPolygon2, typename Strategy>
-struct distance_multi_to_multi
- <
- MultiPolygon1, MultiPolygon2, Strategy,
- multi_polygon_tag, multi_polygon_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- MultiPolygon1, MultiPolygon2, Strategy
- >
-{};
-
-
-} // namespace splitted_dispatch
-
-
-
-
-template
-<
- typename MultiGeometry1,
- typename MultiGeometry2,
- typename Strategy,
- typename StrategyTag
->
-struct distance
- <
- MultiGeometry1, MultiGeometry2, Strategy, multi_tag, multi_tag,
- StrategyTag, false
- > : splitted_dispatch::distance_multi_to_multi
- <
- MultiGeometry1, MultiGeometry2, Strategy,
- typename geometry::tag<MultiGeometry1>::type,
- typename geometry::tag<MultiGeometry2>::type,
- StrategyTag
- >
-{};
-
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-}} // namespace boost::geometry
-
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTI_TO_MULTI_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp
new file mode 100644
index 0000000000..ccd3aa462e
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp
@@ -0,0 +1,239 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+
+#include <boost/geometry/algorithms/covered_by.hpp>
+
+#include <boost/geometry/algorithms/dispatch/distance.hpp>
+
+#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance
+{
+
+
+template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
+struct multipoint_to_multipoint
+{
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<MultiPoint1>::type,
+ typename point_type<MultiPoint2>::type
+ >::type return_type;
+
+ static inline return_type apply(MultiPoint1 const& multipoint1,
+ MultiPoint2 const& multipoint2,
+ Strategy const& strategy)
+ {
+ if (boost::size(multipoint2) < boost::size(multipoint1))
+
+ {
+ return point_or_segment_range_to_geometry_rtree
+ <
+ typename boost::range_iterator<MultiPoint2 const>::type,
+ MultiPoint1,
+ Strategy
+ >::apply(boost::begin(multipoint2),
+ boost::end(multipoint2),
+ multipoint1,
+ strategy);
+ }
+
+ return point_or_segment_range_to_geometry_rtree
+ <
+ typename boost::range_iterator<MultiPoint1 const>::type,
+ MultiPoint2,
+ Strategy
+ >::apply(boost::begin(multipoint1),
+ boost::end(multipoint1),
+ multipoint2,
+ strategy);
+ }
+};
+
+
+template <typename MultiPoint, typename Linear, typename Strategy>
+struct multipoint_to_linear
+{
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<MultiPoint>::type,
+ typename point_type<Linear>::type
+ >::type return_type;
+
+ static inline return_type apply(MultiPoint const& multipoint,
+ Linear const& linear,
+ Strategy const& strategy)
+ {
+ return detail::distance::point_or_segment_range_to_geometry_rtree
+ <
+ typename boost::range_iterator<MultiPoint const>::type,
+ Linear,
+ Strategy
+ >::apply(boost::begin(multipoint),
+ boost::end(multipoint),
+ linear,
+ strategy);
+ }
+
+ static inline return_type apply(Linear const& linear,
+ MultiPoint const& multipoint,
+ Strategy const& strategy)
+ {
+ return apply(multipoint, linear, strategy);
+ }
+};
+
+
+template <typename MultiPoint, typename Areal, typename Strategy>
+class multipoint_to_areal
+{
+private:
+ struct not_covered_by_areal
+ {
+ not_covered_by_areal(Areal const& areal)
+ : m_areal(areal)
+ {}
+
+ template <typename Point>
+ inline bool apply(Point const& point) const
+ {
+ return !geometry::covered_by(point, m_areal);
+ }
+
+ Areal const& m_areal;
+ };
+
+public:
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<MultiPoint>::type,
+ typename point_type<Areal>::type
+ >::type return_type;
+
+ static inline return_type apply(MultiPoint const& multipoint,
+ Areal const& areal,
+ Strategy const& strategy)
+ {
+ not_covered_by_areal predicate(areal);
+
+ if (check_iterator_range
+ <
+ not_covered_by_areal, false
+ >::apply(boost::begin(multipoint),
+ boost::end(multipoint),
+ predicate))
+ {
+ return detail::distance::point_or_segment_range_to_geometry_rtree
+ <
+ typename boost::range_iterator<MultiPoint const>::type,
+ Areal,
+ Strategy
+ >::apply(boost::begin(multipoint),
+ boost::end(multipoint),
+ areal,
+ strategy);
+ }
+ return 0;
+ }
+
+ static inline return_type apply(Areal const& areal,
+ MultiPoint const& multipoint,
+ Strategy const& strategy)
+ {
+ return apply(multipoint, areal, strategy);
+ }
+};
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
+struct distance
+ <
+ MultiPoint1, MultiPoint2, Strategy,
+ multi_point_tag, multi_point_tag,
+ strategy_tag_distance_point_point, false
+ > : detail::distance::multipoint_to_multipoint
+ <
+ MultiPoint1, MultiPoint2, Strategy
+ >
+{};
+
+template <typename MultiPoint, typename Linear, typename Strategy>
+struct distance
+ <
+ MultiPoint, Linear, Strategy, multi_point_tag, linear_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::multipoint_to_linear<MultiPoint, Linear, Strategy>
+{};
+
+
+template <typename Linear, typename MultiPoint, typename Strategy>
+struct distance
+ <
+ Linear, MultiPoint, Strategy, linear_tag, multi_point_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::multipoint_to_linear<MultiPoint, Linear, Strategy>
+{};
+
+
+template <typename MultiPoint, typename Areal, typename Strategy>
+struct distance
+ <
+ MultiPoint, Areal, Strategy, multi_point_tag, areal_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::multipoint_to_areal<MultiPoint, Areal, Strategy>
+{};
+
+
+template <typename Areal, typename MultiPoint, typename Strategy>
+struct distance
+ <
+ Areal, MultiPoint, Strategy, areal_tag, multi_point_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::multipoint_to_areal<MultiPoint, Areal, Strategy>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/multipoint_to_range.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/multipoint_to_range.hpp
deleted file mode 100644
index 1774fab72e..0000000000
--- a/3party/boost/boost/geometry/algorithms/detail/distance/multipoint_to_range.hpp
+++ /dev/null
@@ -1,183 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2014, Oracle and/or its affiliates.
-
-// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
-
-// Licensed under the Boost Software License version 1.0.
-// http://www.boost.org/users/license.html
-
-#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_RANGE_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_RANGE_HPP
-
-#include <boost/range.hpp>
-
-#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/core/point_type.hpp>
-
-#include <boost/geometry/algorithms/dispatch/distance.hpp>
-
-#include <boost/geometry/algorithms/detail/distance/single_to_multi.hpp>
-#include <boost/geometry/algorithms/detail/distance/multi_to_multi.hpp>
-#include <boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp>
-
-#include <boost/geometry/geometries/concepts/check.hpp>
-
-#include <boost/geometry/iterators/point_iterator.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace distance
-{
-
-template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
-struct multipoint_to_multipoint
-{
- typedef typename strategy::distance::services::return_type
- <
- Strategy,
- typename point_type<MultiPoint1>::type,
- typename point_type<MultiPoint2>::type
- >::type return_type;
-
- static inline return_type apply(MultiPoint1 const& multipoint1,
- MultiPoint2 const& multipoint2,
- Strategy const& strategy)
- {
- if ( boost::size(multipoint1) > boost::size(multipoint2) )
-
- {
- return multipoint_to_multipoint
- <
- MultiPoint2, MultiPoint1, Strategy
- >::apply(multipoint2, multipoint1, strategy);
- }
-
- return point_range_to_geometry_rtree
- <
- typename point_type<MultiPoint1>::type,
- MultiPoint2,
- Strategy
- >::apply(points_begin(multipoint1), points_end(multipoint1),
- multipoint2, strategy);
- }
-};
-
-
-}} // namespace detail::distance
-#endif // DOXYGEN_NO_DETAIL
-
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-namespace splitted_dispatch
-{
-
-// specializations of distance_single_to_multi for various geometry combinations
-
-template<typename Linestring, typename MultiPoint, typename Strategy>
-struct distance_single_to_multi
- <
- Linestring, MultiPoint, Strategy,
- linestring_tag, multi_point_tag,
- strategy_tag_distance_point_segment
- >
-{
- typedef typename strategy::distance::services::return_type
- <
- Strategy,
- typename point_type<Linestring>::type,
- typename point_type<MultiPoint>::type
- >::type return_type;
-
- static inline return_type apply(Linestring const& linestring,
- MultiPoint const& multipoint,
- Strategy const& strategy)
- {
- return detail::distance::point_range_to_geometry_rtree
- <
- typename point_type<MultiPoint>::type,
- Linestring,
- Strategy
- >::apply(geometry::points_begin(multipoint),
- geometry::points_end(multipoint),
- linestring, strategy);
-
- }
-};
-
-
-
-
-// specializations of distance_multi_to_multi for various geometry combinations
-
-
-template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
-struct distance_multi_to_multi
- <
- MultiPoint1, MultiPoint2, Strategy,
- multi_point_tag, multi_point_tag,
- strategy_tag_distance_point_point
- > : detail::distance::multipoint_to_multipoint
- <
- MultiPoint1, MultiPoint2, Strategy
- >
-{};
-
-
-
-template
-<
- typename MultiPoint,
- typename MultiLinestring,
- typename Strategy
->
-struct distance_multi_to_multi
- <
- MultiPoint, MultiLinestring, Strategy,
- multi_point_tag, multi_linestring_tag,
- strategy_tag_distance_point_segment
- >
-{
- typedef typename strategy::distance::services::return_type
- <
- Strategy,
- typename point_type<MultiPoint>::type,
- typename point_type<MultiLinestring>::type
- >::type return_type;
-
- static inline return_type apply(MultiPoint const& multipoint,
- MultiLinestring const& multilinestring,
- Strategy const& strategy)
- {
- return detail::distance::point_range_to_geometry_rtree
- <
- typename point_type<MultiPoint>::type,
- MultiLinestring,
- Strategy
- >::apply(geometry::points_begin(multipoint),
- geometry::points_end(multipoint),
- multilinestring, strategy);
-
- }
-};
-
-} // namespace splitted_dispatch
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-
-}} // namespace boost::geometry
-
-
-#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_ALTERNATE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp
index a46f1fe7d1..ab5de3d9b2 100644
--- a/3party/boost/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp
@@ -20,32 +20,34 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POINT_TO_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POINT_TO_GEOMETRY_HPP
-#include <utility>
+#include <iterator>
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
+#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
-#include <boost/geometry/core/interior_type.hpp>
+#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
-#include <boost/geometry/strategies/distance_comparable_to_regular.hpp>
-
-#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/within.hpp>
-#include <boost/geometry/algorithms/intersects.hpp>
-#include <boost/geometry/algorithms/dispatch/distance.hpp>
+#include <boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp>
+#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
+#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
+#include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
-#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
+#include <boost/geometry/algorithms/dispatch/distance.hpp>
namespace boost { namespace geometry
@@ -63,7 +65,7 @@ struct point_to_point
typename strategy::distance::services::return_type<Strategy, P1, P2>::type
apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
{
- boost::ignore_unused_variable_warning(strategy);
+ boost::ignore_unused(strategy);
return strategy.apply(p1, p2);
}
};
@@ -84,12 +86,10 @@ private:
Strategy
>::type comparable_strategy;
- typedef typename strategy::distance::services::return_type
+ typedef detail::closest_feature::point_to_point_range
<
- comparable_strategy,
- Point,
- typename boost::range_value<Range>::type
- >::type comparable_return_type;
+ Point, Range, Closure, comparable_strategy
+ > point_to_point_range;
public:
typedef typename strategy::distance::services::return_type
@@ -102,68 +102,42 @@ public:
static inline return_type apply(Point const& point, Range const& range,
Strategy const& strategy)
{
- comparable_strategy c_strategy =
- strategy::distance::services::get_comparable
- <
- Strategy
- >::apply(strategy);
-
- comparable_return_type const zero = comparable_return_type(0);
+ return_type const zero = return_type(0);
if (boost::size(range) == 0)
{
return zero;
}
- typedef typename closeable_view<Range const, Closure>::type view_type;
+ namespace sds = strategy::distance::services;
- 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 strategy::distance::services::comparable_to_regular
- <
- comparable_strategy, Strategy, Point,
- typename boost::range_value<Range>::type
- >::apply( c_strategy.apply(point,
- *boost::begin(view),
- *boost::begin(view)) );
- }
-
- // start with first segment distance
- comparable_return_type cd = c_strategy.apply(point, *prev, *it);
-
- // check if other segments are closer
- for (++prev, ++it; it != boost::end(view); ++prev, ++it)
- {
- comparable_return_type cds = c_strategy.apply(point, *prev, *it);
- if (geometry::math::equals(cds, zero))
- {
- return strategy::distance::services::comparable_to_regular
- <
- comparable_strategy,
- Strategy,
- Point,
- typename boost::range_value<Range>::type
- >::apply(zero);
- }
- else if (cds < cd)
- {
- cd = cds;
- }
- }
-
- return strategy::distance::services::comparable_to_regular
+ typename sds::return_type
<
comparable_strategy,
- Strategy,
Point,
- typename boost::range_value<Range>::type
- >::apply(cd);
+ typename point_type<Range>::type
+ >::type cd_min;
+
+ std::pair
+ <
+ typename boost::range_iterator<Range const>::type,
+ typename boost::range_iterator<Range const>::type
+ > it_pair
+ = point_to_point_range::apply(point,
+ boost::begin(range),
+ boost::end(range),
+ sds::get_comparable
+ <
+ Strategy
+ >::apply(strategy),
+ cd_min);
+
+ return
+ is_comparable<Strategy>::value
+ ?
+ cd_min
+ :
+ strategy.apply(point, *it_pair.first, *it_pair.second);
}
};
@@ -177,35 +151,28 @@ template
>
struct point_to_ring
{
- typedef std::pair
+ typedef typename strategy::distance::services::return_type
<
- typename strategy::distance::services::return_type
- <
- Strategy, Point, typename point_type<Ring>::type
- >::type,
- bool
- > distance_containment;
-
- static inline distance_containment apply(Point const& point,
- Ring const& ring,
- Strategy const& strategy)
+ Strategy, Point, typename point_type<Ring>::type
+ >::type return_type;
+
+ static inline return_type apply(Point const& point,
+ Ring const& ring,
+ Strategy const& strategy)
{
- return distance_containment
- (
- point_to_range
- <
- Point,
- Ring,
- Closure,
- Strategy
- >::apply(point, ring, strategy),
- geometry::within(point, ring)
- );
+ if (geometry::within(point, ring))
+ {
+ return return_type(0);
+ }
+
+ return point_to_range
+ <
+ Point, Ring, closure<Ring>::value, Strategy
+ >::apply(point, ring, strategy);
}
};
-
template
<
typename Point,
@@ -215,79 +182,163 @@ template
>
class point_to_polygon
{
-private:
- typedef typename strategy::distance::services::comparable_type
+public:
+ typedef typename strategy::distance::services::return_type
<
- Strategy
- >::type comparable_strategy;
+ Strategy, Point, typename point_type<Polygon>::type
+ >::type return_type;
- typedef typename strategy::distance::services::return_type
+private:
+ typedef point_to_range
<
- comparable_strategy, Point, typename point_type<Polygon>::type
- >::type comparable_return_type;
+ Point, typename ring_type<Polygon>::type, Closure, Strategy
+ > per_ring;
+
+ struct distance_to_interior_rings
+ {
+ template <typename InteriorRingIterator>
+ static inline return_type apply(Point const& point,
+ InteriorRingIterator first,
+ InteriorRingIterator last,
+ Strategy const& strategy)
+ {
+ for (InteriorRingIterator it = first; it != last; ++it)
+ {
+ if (geometry::within(point, *it))
+ {
+ // the point is inside a polygon hole, so its distance
+ // to the polygon its distance to the polygon's
+ // hole boundary
+ return per_ring::apply(point, *it, strategy);
+ }
+ }
+ return 0;
+ }
+
+ template <typename InteriorRings>
+ static inline return_type apply(Point const& point,
+ InteriorRings const& interior_rings,
+ Strategy const& strategy)
+ {
+ return apply(point,
+ boost::begin(interior_rings),
+ boost::end(interior_rings),
+ strategy);
+ }
+ };
- typedef std::pair
+
+public:
+ static inline return_type apply(Point const& point,
+ Polygon const& polygon,
+ Strategy const& strategy)
+ {
+ if (!geometry::covered_by(point, exterior_ring(polygon)))
+ {
+ // the point is outside the exterior ring, so its distance
+ // to the polygon is its distance to the polygon's exterior ring
+ return per_ring::apply(point, exterior_ring(polygon), strategy);
+ }
+
+ // Check interior rings
+ return distance_to_interior_rings::apply(point,
+ interior_rings(polygon),
+ strategy);
+ }
+};
+
+
+template
+<
+ typename Point,
+ typename MultiGeometry,
+ typename Strategy,
+ bool CheckCoveredBy = boost::is_same
<
- comparable_return_type, bool
- > comparable_distance_containment;
+ typename tag<MultiGeometry>::type, multi_polygon_tag
+ >::value
+>
+class point_to_multigeometry
+{
+private:
+ typedef detail::closest_feature::geometry_to_range geometry_to_range;
public:
typedef typename strategy::distance::services::return_type
<
- Strategy, Point, typename point_type<Polygon>::type
+ Strategy,
+ Point,
+ typename point_type<MultiGeometry>::type
>::type return_type;
- typedef std::pair<return_type, bool> distance_containment;
- static inline distance_containment apply(Point const& point,
- Polygon const& polygon,
- Strategy const& strategy)
+ static inline return_type apply(Point const& point,
+ MultiGeometry const& multigeometry,
+ Strategy const& strategy)
{
- comparable_strategy c_strategy =
- strategy::distance::services::get_comparable
- <
- Strategy
- >::apply(strategy);
+ typedef iterator_selector<MultiGeometry const> selector_type;
+
+ namespace sds = strategy::distance::services;
- // Check distance to all rings
- typedef point_to_ring
+ typename sds::return_type
<
+ typename sds::comparable_type<Strategy>::type,
Point,
- typename ring_type<Polygon>::type,
- Closure,
- comparable_strategy
- > per_ring;
-
- comparable_distance_containment dc =
- per_ring::apply(point, exterior_ring(polygon), c_strategy);
-
- typename interior_return_type<Polygon const>::type rings
- = interior_rings(polygon);
- for (typename boost::range_iterator
- <
- typename interior_type<Polygon const>::type const
- >::type it = boost::begin(rings);
- it != boost::end(rings); ++it)
+ typename point_type<MultiGeometry>::type
+ >::type cd;
+
+ typename selector_type::iterator_type it_min
+ = geometry_to_range::apply(point,
+ selector_type::begin(multigeometry),
+ selector_type::end(multigeometry),
+ sds::get_comparable
+ <
+ Strategy
+ >::apply(strategy),
+ cd);
+
+ return
+ is_comparable<Strategy>::value
+ ?
+ cd
+ :
+ dispatch::distance
+ <
+ Point,
+ typename std::iterator_traits
+ <
+ typename selector_type::iterator_type
+ >::value_type,
+ Strategy
+ >::apply(point, *it_min, strategy);
+ }
+};
+
+
+// this is called only for multipolygons, hence the change in the
+// template parameter name MultiGeometry to MultiPolygon
+template <typename Point, typename MultiPolygon, typename Strategy>
+struct point_to_multigeometry<Point, MultiPolygon, Strategy, true>
+{
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ Point,
+ typename point_type<MultiPolygon>::type
+ >::type return_type;
+
+ static inline return_type apply(Point const& point,
+ MultiPolygon const& multipolygon,
+ Strategy const& strategy)
+ {
+ if (geometry::covered_by(point, multipolygon))
{
- comparable_distance_containment dcr =
- per_ring::apply(point, *it, c_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 0;
}
- return_type rd = strategy::distance::services::comparable_to_regular
+ return point_to_multigeometry
<
- comparable_strategy, Strategy, Point, Polygon
- >::apply(dc.first);
-
- return std::make_pair(rd, dc.second);
+ Point, MultiPolygon, Strategy, false
+ >::apply(point, multipolygon, strategy);
}
};
@@ -307,111 +358,73 @@ namespace dispatch
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>
+ P1, P2, Strategy, point_tag, point_tag,
+ strategy_tag_distance_point_point, false
+ > : detail::distance::point_to_point<P1, P2, Strategy>
{};
// 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
-> : detail::distance::point_to_range<Point, Linestring, closed, Strategy>
+ <
+ Point, Linestring, Strategy, point_tag, linestring_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::point_to_range<Point, Linestring, closed, 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_segment,
- false
->
-{
- typedef typename strategy::distance::services::return_type
+ <
+ Point, Ring, Strategy, point_tag, ring_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::point_to_ring
<
- Strategy, Point, typename point_type<Ring>::type
- >::type return_type;
-
- static inline return_type apply(Point const& point,
- Ring const& ring,
- Strategy const& strategy)
- {
- std::pair<return_type, bool>
- dc = detail::distance::point_to_ring
- <
- Point, Ring,
- geometry::closure<Ring>::value,
- Strategy
- >::apply(point, ring, strategy);
-
- return dc.second ? return_type(0) : dc.first;
- }
-};
+ Point, Ring, closure<Ring>::value, Strategy
+ >
+{};
// 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_segment, false
->
-{
- typedef typename strategy::distance::services::return_type
+ <
+ Point, Polygon, Strategy, point_tag, polygon_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::point_to_polygon
<
- Strategy, Point, typename point_type<Polygon>::type
- >::type return_type;
-
- static inline return_type apply(Point const& point,
- Polygon const& polygon,
- Strategy const& strategy)
- {
- std::pair<return_type, bool>
- dc = detail::distance::point_to_polygon
- <
- Point, Polygon,
- geometry::closure<Polygon>::value,
- Strategy
- >::apply(point, polygon, strategy);
-
- return dc.second ? return_type(0) : dc.first;
- }
-};
+ Point, Polygon, closure<Polygon>::value, 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
->
+ <
+ Point, Segment, Strategy, point_tag, segment_tag,
+ strategy_tag_distance_point_segment, false
+ >
{
- static inline typename return_type<Strategy, Point, typename point_type<Segment>::type>::type
- apply(Point const& point,
- Segment const& segment,
- Strategy const& strategy)
+ static inline typename strategy::distance::services::return_type
+ <
+ Strategy, Point, typename point_type<Segment>::type
+ >::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]);
- boost::ignore_unused_variable_warning(strategy);
+ boost::ignore_unused(strategy);
return strategy.apply(point, p[0], p[1]);
}
};
-
template <typename Point, typename Box, typename Strategy>
struct distance
<
@@ -425,12 +438,75 @@ struct distance
>::type
apply(Point const& point, Box const& box, Strategy const& strategy)
{
- boost::ignore_unused_variable_warning(strategy);
+ boost::ignore_unused(strategy);
return strategy.apply(point, box);
}
};
+template<typename Point, typename MultiPoint, typename Strategy>
+struct distance
+ <
+ Point, MultiPoint, Strategy, point_tag, multi_point_tag,
+ strategy_tag_distance_point_point, false
+ > : detail::distance::point_to_multigeometry
+ <
+ Point, MultiPoint, Strategy
+ >
+{};
+
+
+template<typename Point, typename MultiLinestring, typename Strategy>
+struct distance
+ <
+ Point, MultiLinestring, Strategy, point_tag, multi_linestring_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::point_to_multigeometry
+ <
+ Point, MultiLinestring, Strategy
+ >
+{};
+
+
+template<typename Point, typename MultiPolygon, typename Strategy>
+struct distance
+ <
+ Point, MultiPolygon, Strategy, point_tag, multi_polygon_tag,
+ strategy_tag_distance_point_segment, false
+ > : detail::distance::point_to_multigeometry
+ <
+ Point, MultiPolygon, Strategy
+ >
+{};
+
+
+template <typename Point, typename Linear, typename Strategy>
+struct distance
+ <
+ Point, Linear, Strategy, point_tag, linear_tag,
+ strategy_tag_distance_point_segment, false
+ > : distance
+ <
+ Point, Linear, Strategy,
+ point_tag, typename tag<Linear>::type,
+ strategy_tag_distance_point_segment, false
+ >
+{};
+
+
+template <typename Point, typename Areal, typename Strategy>
+struct distance
+ <
+ Point, Areal, Strategy, point_tag, areal_tag,
+ strategy_tag_distance_point_segment, false
+ > : distance
+ <
+ Point, Areal, Strategy,
+ point_tag, typename tag<Areal>::type,
+ strategy_tag_distance_point_segment, false
+ >
+{};
+
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp
deleted file mode 100644
index 631cb25d37..0000000000
--- a/3party/boost/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp
+++ /dev/null
@@ -1,160 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2014, Oracle and/or its affiliates.
-
-// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
-
-// Licensed under the Boost Software License version 1.0.
-// http://www.boost.org/users/license.html
-
-#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POLYGON_TO_SEGMENT_OR_BOX_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POLYGON_TO_SEGMENT_OR_BOX_HPP
-
-#include <boost/range.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/tags.hpp>
-
-#include <boost/geometry/strategies/distance.hpp>
-#include <boost/geometry/strategies/distance_comparable_to_regular.hpp>
-#include <boost/geometry/strategies/tags.hpp>
-
-#include <boost/geometry/algorithms/assign.hpp>
-#include <boost/geometry/algorithms/within.hpp>
-#include <boost/geometry/algorithms/intersects.hpp>
-
-#include <boost/geometry/util/math.hpp>
-
-#include <boost/geometry/algorithms/dispatch/distance.hpp>
-
-#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
-#include <boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace distance
-{
-
-
-template <typename Polygon, typename SegmentOrBox, typename Strategy>
-class polygon_to_segment_or_box
-{
-private:
- typedef typename strategy::distance::services::comparable_type
- <
- Strategy
- >::type comparable_strategy;
-
- typedef typename strategy::distance::services::return_type
- <
- comparable_strategy,
- typename point_type<Polygon>::type,
- typename point_type<SegmentOrBox>::type
- >::type comparable_return_type;
-
-public:
- typedef typename strategy::distance::services::return_type
- <
- Strategy,
- typename point_type<Polygon>::type,
- typename point_type<SegmentOrBox>::type
- >::type return_type;
-
- static inline return_type apply(Polygon const& polygon,
- SegmentOrBox const& segment_or_box,
- Strategy const& strategy)
- {
- typedef typename geometry::ring_type<Polygon>::type e_ring;
- typedef typename geometry::interior_type<Polygon>::type i_rings;
- typedef typename range_value<i_rings>::type i_ring;
-
- if ( geometry::intersects(polygon, segment_or_box) )
- {
- return 0;
- }
-
- e_ring const& ext_ring = geometry::exterior_ring<Polygon>(polygon);
- i_rings const& int_rings = geometry::interior_rings<Polygon>(polygon);
-
- comparable_strategy cstrategy =
- strategy::distance::services::get_comparable
- <
- Strategy
- >::apply(strategy);
-
-
- comparable_return_type cd_min = range_to_segment_or_box
- <
- e_ring, SegmentOrBox, comparable_strategy
- >::apply(ext_ring, segment_or_box, cstrategy, false);
-
- typedef typename boost::range_iterator<i_rings const>::type iterator_type;
- for (iterator_type it = boost::begin(int_rings);
- it != boost::end(int_rings); ++it)
- {
- comparable_return_type cd = range_to_segment_or_box
- <
- i_ring, SegmentOrBox, comparable_strategy
- >::apply(*it, segment_or_box, cstrategy, false);
-
- if ( cd < cd_min )
- {
- cd_min = cd;
- }
- }
-
- return strategy::distance::services::comparable_to_regular
- <
- comparable_strategy,
- Strategy,
- Polygon,
- SegmentOrBox
- >::apply(cd_min);
- }
-};
-
-
-}} // namespace detail::distance
-#endif // DOXYGEN_NO_DETAIL
-
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace dispatch
-{
-
-
-template <typename Polygon, typename Segment, typename Strategy>
-struct distance
- <
- Polygon, Segment, Strategy, polygon_tag, segment_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::polygon_to_segment_or_box<Polygon, Segment, Strategy>
-{};
-
-
-
-template <typename Polygon, typename Box, typename Strategy>
-struct distance
- <
- Polygon, Box, Strategy, polygon_tag, box_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::polygon_to_segment_or_box<Polygon, Box, Strategy>
-{};
-
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DETAIL
-
-}} // namespace boost::geometry
-
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POLYGON_TO_SEGMENT_OR_BOX_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp
new file mode 100644
index 0000000000..6e78bee694
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp
@@ -0,0 +1,130 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP
+
+#include <iterator>
+#include <utility>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/iterators/has_one_element.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+#include <boost/geometry/algorithms/dispatch/distance.hpp>
+
+#include <boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp>
+#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
+#include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance
+{
+
+
+template
+<
+ typename PointOrSegmentIterator,
+ typename Geometry,
+ typename Strategy
+>
+class point_or_segment_range_to_geometry_rtree
+{
+private:
+ typedef typename std::iterator_traits
+ <
+ PointOrSegmentIterator
+ >::value_type point_or_segment_type;
+
+ typedef iterator_selector<Geometry const> selector_type;
+
+ typedef detail::closest_feature::range_to_range_rtree range_to_range;
+
+public:
+ typedef typename strategy::distance::services::return_type
+ <
+ Strategy,
+ typename point_type<point_or_segment_type>::type,
+ typename point_type<Geometry>::type
+ >::type return_type;
+
+ static inline return_type apply(PointOrSegmentIterator first,
+ PointOrSegmentIterator last,
+ Geometry const& geometry,
+ Strategy const& strategy)
+ {
+ namespace sds = strategy::distance::services;
+
+ BOOST_GEOMETRY_ASSERT( first != last );
+
+ if ( geometry::has_one_element(first, last) )
+ {
+ return dispatch::distance
+ <
+ point_or_segment_type, Geometry, Strategy
+ >::apply(*first, geometry, strategy);
+ }
+
+ typename sds::return_type
+ <
+ typename sds::comparable_type<Strategy>::type,
+ typename point_type<point_or_segment_type>::type,
+ typename point_type<Geometry>::type
+ >::type cd_min;
+
+ std::pair
+ <
+ point_or_segment_type,
+ typename selector_type::iterator_type
+ > closest_features
+ = range_to_range::apply(first,
+ last,
+ selector_type::begin(geometry),
+ selector_type::end(geometry),
+ sds::get_comparable
+ <
+ Strategy
+ >::apply(strategy),
+ cd_min);
+
+ return
+ is_comparable<Strategy>::value
+ ?
+ cd_min
+ :
+ dispatch::distance
+ <
+ point_or_segment_type,
+ typename std::iterator_traits
+ <
+ typename selector_type::iterator_type
+ >::value_type,
+ Strategy
+ >::apply(closest_features.first,
+ *closest_features.second,
+ strategy);
+ }
+};
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp
deleted file mode 100644
index 8d02e1cce0..0000000000
--- a/3party/boost/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp
+++ /dev/null
@@ -1,333 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2014, Oracle and/or its affiliates.
-
-// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
-
-// Licensed under the Boost Software License version 1.0.
-// http://www.boost.org/users/license.html
-
-#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_SEGMENT_OR_BOX_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_SEGMENT_OR_BOX_HPP
-
-#include <vector>
-
-#include <boost/range.hpp>
-
-#include <boost/geometry/core/closure.hpp>
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/reverse_dispatch.hpp>
-#include <boost/geometry/core/tag.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/strategies/distance.hpp>
-#include <boost/geometry/strategies/distance_comparable_to_regular.hpp>
-#include <boost/geometry/strategies/tags.hpp>
-
-#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
-#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
-#include <boost/geometry/algorithms/intersects.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
-
-#include <boost/geometry/algorithms/dispatch/distance.hpp>
-
-#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace distance
-{
-
-
-
-template
-<
- typename Range,
- typename SegmentOrBox,
- typename Strategy
->
-class range_to_segment_or_box
-{
-private:
- typedef typename point_type<SegmentOrBox>::type segment_or_box_point;
- typedef typename point_type<Range>::type range_point;
-
- typedef typename strategy::distance::services::comparable_type
- <
- Strategy
- >::type comparable_strategy;
-
- typedef typename strategy::distance::services::return_type
- <
- comparable_strategy, range_point, segment_or_box_point
- >::type comparable_return_type;
-
- typedef typename strategy::distance::services::tag
- <
- comparable_strategy
- >::type comparable_strategy_tag;
-
- typedef dispatch::distance
- <
- segment_or_box_point, Range, comparable_strategy,
- point_tag, typename tag<Range>::type,
- comparable_strategy_tag, false
- > comparable_point_to_range;
-
- // compute distance of a point to a segment or a box
- template
- <
- typename Point,
- typename SegOrBoxPoints,
- typename ComparableStrategy,
- typename Tag
- >
- struct comparable_distance_point_to_segment_or_box
- {};
-
- template
- <
- typename Point,
- typename SegmentPoints,
- typename ComparableStrategy
- >
- struct comparable_distance_point_to_segment_or_box
- <
- Point, SegmentPoints, ComparableStrategy, segment_tag
- >
- {
- static inline
- comparable_return_type apply(Point const& point,
- SegmentPoints const& segment_points,
- ComparableStrategy const& strategy)
- {
- boost::ignore_unused_variable_warning(strategy);
- return strategy.apply(point, segment_points[0], segment_points[1]);
- }
- };
-
- template
- <
- typename Point,
- typename BoxPoints,
- typename ComparableStrategy
- >
- struct comparable_distance_point_to_segment_or_box
- <
- Point, BoxPoints, ComparableStrategy, box_tag
- >
- {
- static inline
- comparable_return_type apply(Point const& point,
- BoxPoints const& box_points,
- ComparableStrategy const& strategy)
- {
- return point_to_range
- <
- Point, BoxPoints, open, ComparableStrategy
- >::apply(point, box_points, strategy);
- }
- };
-
-
- // assign the points of a segment or a box to a range
- template
- <
- typename SegOrBox,
- typename PointRange,
- typename Tag = typename tag<SegOrBox>::type
- >
- struct assign_segment_or_box_points
- {};
-
-
- template <typename Segment, typename PointRange>
- struct assign_segment_or_box_points<Segment, PointRange, segment_tag>
- {
- static inline void apply(Segment const& segment, PointRange& range)
- {
- detail::assign_point_from_index<0>(segment, range[0]);
- detail::assign_point_from_index<1>(segment, range[1]);
- }
- };
-
- template <typename Box, typename PointRange>
- struct assign_segment_or_box_points<Box, PointRange, box_tag>
- {
- static inline void apply(Box const& box, PointRange& range)
- {
- detail::assign_box_corners_oriented<true>(box, range);
- }
- };
-
-
-public:
- typedef typename strategy::distance::services::return_type
- <
- Strategy, range_point, segment_or_box_point
- >::type return_type;
-
- static inline return_type
- apply(Range const& range, SegmentOrBox const& segment_or_box,
- Strategy const& strategy, bool check_intersection = true)
- {
- if ( check_intersection && geometry::intersects(range, segment_or_box) )
- {
- return 0;
- }
-
- comparable_strategy cstrategy =
- strategy::distance::services::get_comparable
- <
- Strategy
- >::apply(strategy);
-
-
- // get all points of the segment or the box
- std::vector<segment_or_box_point>
- segment_or_box_points(geometry::num_points(segment_or_box));
-
- assign_segment_or_box_points
- <
-
- SegmentOrBox,
- std::vector<segment_or_box_point>
- >::apply(segment_or_box, segment_or_box_points);
-
- // consider all distances from each endpoint of the segment or box
- // to the range
- typename std::vector<segment_or_box_point>::const_iterator it
- = segment_or_box_points.begin();
- comparable_return_type cd_min =
- comparable_point_to_range::apply(*it, range, cstrategy);
-
- for (++it; it != segment_or_box_points.end(); ++it)
- {
- comparable_return_type cd =
- comparable_point_to_range::apply(*it, range, cstrategy);
- if ( cd < cd_min )
- {
- cd_min = cd;
- }
- }
-
- // consider all distances of the points in the range to the
- // segment or box
- typedef typename range_iterator<Range const>::type iterator_type;
- for (iterator_type it = boost::begin(range); it != boost::end(range); ++it)
- {
- comparable_return_type cd =
- comparable_distance_point_to_segment_or_box
- <
- typename point_type<Range>::type,
- std::vector<segment_or_box_point>,
- comparable_strategy,
- typename tag<SegmentOrBox>::type
- >::apply(*it, segment_or_box_points, cstrategy);
-
- if ( cd < cd_min )
- {
- cd_min = cd;
- }
- }
-
- return strategy::distance::services::comparable_to_regular
- <
- comparable_strategy, Strategy,
- range_point, segment_or_box_point
- >::apply(cd_min);
- }
-
- static inline return_type
- apply(SegmentOrBox const& segment_or_box, Range const& range,
- Strategy const& strategy, bool check_intersection = true)
- {
- return apply(range, segment_or_box, strategy, check_intersection);
- }
-};
-
-
-}} // namespace detail::distance
-#endif // DOXYGEN_NO_DETAIL
-
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-
-template <typename Linestring, typename Segment, typename Strategy>
-struct distance
- <
- Linestring, Segment, Strategy, linestring_tag, segment_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::range_to_segment_or_box
- <
- Linestring, Segment, Strategy
- >
-{};
-
-
-
-
-template <typename Segment, typename Ring, typename Strategy>
-struct distance
- <
- Segment, Ring, Strategy, segment_tag, ring_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::range_to_segment_or_box
- <
- Ring, Segment, Strategy
- >
-{};
-
-
-
-
-template <typename Linestring, typename Box, typename Strategy>
-struct distance
- <
- Linestring, Box, Strategy, linestring_tag, box_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::range_to_segment_or_box
- <
- Linestring, Box, Strategy
- >
-{};
-
-
-
-
-template <typename Ring, typename Box, typename Strategy>
-struct distance
- <
- Ring, Box, Strategy, ring_tag, box_tag,
- strategy_tag_distance_point_segment, false
- >
- : detail::distance::range_to_segment_or_box
- <
- Ring, Box, Strategy
- >
-{};
-
-
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-
-}} // namespace boost::geometry
-
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_SEGMENT_OR_BOX_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/segment_to_box.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
index 695f3a2bec..783699ee0a 100644
--- a/3party/boost/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
@@ -10,24 +10,28 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
+#include <cstddef>
+
#include <functional>
#include <vector>
-#include <boost/assert.hpp>
+#include <boost/core/ignore_unused.hpp>
+#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_same.hpp>
-#include <boost/mpl/if.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/calculation_type.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/strategies/distance.hpp>
-#include <boost/geometry/strategies/distance_comparable_to_regular.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/policies/compare.hpp>
@@ -39,7 +43,7 @@
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
-#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
+#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
@@ -72,16 +76,19 @@ private:
Strategy
>::type comparable_strategy;
+ typedef detail::closest_feature::point_to_point_range
+ <
+ segment_point,
+ std::vector<box_point>,
+ open,
+ comparable_strategy
+ > point_to_point_range;
+
typedef typename strategy::distance::services::return_type
<
comparable_strategy, segment_point, box_point
>::type comparable_return_type;
- typedef point_to_range
- <
- segment_point, std::vector<box_point>, open, comparable_strategy
- > point_to_box_boundary;
-
public:
typedef typename strategy::distance::services::return_type
<
@@ -93,7 +100,7 @@ public:
Strategy const& strategy,
bool check_intersection = true)
{
- if ( check_intersection && geometry::intersects(segment, box) )
+ if (check_intersection && geometry::intersects(segment, box))
{
return 0;
}
@@ -103,7 +110,6 @@ public:
<
Strategy
>::apply(strategy);
- boost::ignore_unused_variable_warning(cstrategy);
// get segment points
segment_point p[2];
@@ -119,13 +125,49 @@ public:
{
cd[i] = cstrategy.apply(box_points[i], p[0], p[1]);
}
- cd[4] = point_to_box_boundary::apply(p[0], box_points, cstrategy);
- cd[5] = point_to_box_boundary::apply(p[1], box_points, cstrategy);
- return strategy::distance::services::comparable_to_regular
+ std::pair
<
- comparable_strategy, Strategy, Segment, Box
- >::apply( *std::min_element(cd, cd + 6) );
+ typename std::vector<box_point>::const_iterator,
+ typename std::vector<box_point>::const_iterator
+ > bit_min[2];
+
+ bit_min[0] = point_to_point_range::apply(p[0],
+ box_points.begin(),
+ box_points.end(),
+ cstrategy,
+ cd[4]);
+ bit_min[1] = point_to_point_range::apply(p[1],
+ box_points.begin(),
+ box_points.end(),
+ cstrategy,
+ cd[5]);
+
+ unsigned int imin = 0;
+ for (unsigned int i = 1; i < 6; ++i)
+ {
+ if (cd[i] < cd[imin])
+ {
+ imin = i;
+ }
+ }
+
+ if (BOOST_GEOMETRY_CONDITION(is_comparable<Strategy>::value))
+ {
+ return cd[imin];
+ }
+
+ if (imin < 4)
+ {
+ return strategy.apply(box_points[imin], p[0], p[1]);
+ }
+ else
+ {
+ unsigned int bimin = imin - 4;
+ return strategy.apply(p[bimin],
+ *bit_min[bimin].first,
+ *bit_min[bimin].second);
+ }
}
};
@@ -152,12 +194,14 @@ private:
comparable_strategy, segment_point, box_point
>::type comparable_return_type;
+ typedef typename detail::distance::default_strategy
+ <
+ segment_point, Box
+ >::type point_box_strategy;
+
typedef typename strategy::distance::services::comparable_type
<
- typename detail::distance::default_strategy
- <
- segment_point, Box
- >::type
+ point_box_strategy
>::type point_box_comparable_strategy;
public:
@@ -171,7 +215,7 @@ public:
Strategy const& strategy,
bool check_intersection = true)
{
- if ( check_intersection && geometry::intersects(segment, box) )
+ if (check_intersection && geometry::intersects(segment, box))
{
return 0;
}
@@ -181,7 +225,7 @@ public:
<
Strategy
>::apply(strategy);
- boost::ignore_unused_variable_warning(cstrategy);
+ boost::ignore_unused(cstrategy);
// get segment points
segment_point p[2];
@@ -199,14 +243,32 @@ public:
}
point_box_comparable_strategy pb_cstrategy;
- boost::ignore_unused_variable_warning(pb_cstrategy);
+ boost::ignore_unused(pb_cstrategy);
cd[4] = pb_cstrategy.apply(p[0], box);
cd[5] = pb_cstrategy.apply(p[1], box);
- return strategy::distance::services::comparable_to_regular
- <
- comparable_strategy, Strategy, Segment, Box
- >::apply( *std::min_element(cd, cd + 6) );
+ unsigned int imin = 0;
+ for (unsigned int i = 1; i < 6; ++i)
+ {
+ if (cd[i] < cd[imin])
+ {
+ imin = i;
+ }
+ }
+
+ if (is_comparable<Strategy>::value)
+ {
+ return cd[imin];
+ }
+
+ if (imin < 4)
+ {
+ strategy.apply(box_points[imin], p[0], p[1]);
+ }
+ else
+ {
+ return point_box_strategy().apply(p[imin - 4], box);
+ }
}
};
@@ -281,6 +343,8 @@ private:
PPStrategy const& pp_strategy,
PSStrategy const& ps_strategy)
{
+ boost::ignore_unused(pp_strategy, ps_strategy);
+
// the implementation below is written for non-negative slope
// segments
//
@@ -291,19 +355,22 @@ private:
LessEqual less_equal;
- if ( less_equal(geometry::get<1>(top_right), geometry::get<1>(p0)) )
+ if (less_equal(geometry::get<1>(top_right), geometry::get<1>(p0)))
{
// closest box point is the top-right corner
return cast::apply(pp_strategy.apply(p0, top_right));
}
- else if ( less_equal(geometry::get<1>(bottom_right),
- geometry::get<1>(p0)) )
+ else if (less_equal(geometry::get<1>(bottom_right),
+ geometry::get<1>(p0)))
{
// distance is realized between p0 and right-most
// segment of box
ReturnType diff = cast::apply(geometry::get<0>(p0))
- cast::apply(geometry::get<0>(bottom_right));
- return diff * diff;
+ return strategy::distance::services::result_from_distance
+ <
+ PSStrategy, BoxPoint, SegmentPoint
+ >::apply(ps_strategy, math::abs(diff));
}
else
{
@@ -325,6 +392,8 @@ private:
BoxPoint const& top_left,
PSStrategy const& ps_strategy)
{
+ boost::ignore_unused(ps_strategy);
+
// the segment lies above the box
typedef cast_to_result<ReturnType> cast;
@@ -333,11 +402,14 @@ private:
// p0 is above the upper segment of the box
// (and inside its band)
- if ( less_equal(geometry::get<0>(top_left), geometry::get<0>(p0)) )
+ if (less_equal(geometry::get<0>(top_left), geometry::get<0>(p0)))
{
ReturnType diff = cast::apply(geometry::get<1>(p0))
- cast::apply(geometry::get<1>(top_left));
- return diff * diff;
+ return strategy::distance::services::result_from_distance
+ <
+ PSStrategy, SegmentPoint, BoxPoint
+ >::apply(ps_strategy, math::abs(diff));
}
// p0 is to the left of the box, but p1 is above the box
@@ -362,7 +434,7 @@ private:
ReturnType& result)
{
// p0 lies to the right of the box
- if ( geometry::get<0>(p0) >= geometry::get<0>(top_right) )
+ if (geometry::get<0>(p0) >= geometry::get<0>(top_right))
{
result = right_of_box
<
@@ -373,7 +445,7 @@ private:
}
// p1 lies to the left of the box
- if ( geometry::get<0>(p1) <= geometry::get<0>(bottom_left) )
+ if (geometry::get<0>(p1) <= geometry::get<0>(bottom_left))
{
result = right_of_box
<
@@ -401,7 +473,7 @@ private:
ReturnType& result)
{
// the segment lies below the box
- if ( geometry::get<1>(p1) < geometry::get<1>(bottom_left) )
+ if (geometry::get<1>(p1) < geometry::get<1>(bottom_left))
{
result = above_of_box
<
@@ -411,7 +483,7 @@ private:
}
// the segment lies above the box
- if ( geometry::get<1>(p0) > geometry::get<1>(top_right) )
+ if (geometry::get<1>(p0) > geometry::get<1>(top_right))
{
result = above_of_box
<
@@ -452,7 +524,7 @@ private:
ReturnType t_max1 = cast::apply(geometry::get<1>(top_right1))
- cast::apply(geometry::get<1>(p0));
- if ( diff1 < 0 )
+ if (diff1 < 0)
{
diff1 = -diff1;
t_min1 = -t_min1;
@@ -460,14 +532,14 @@ private:
}
// t_min0 > t_max1
- if ( t_min0 * diff1 > t_max1 * diff0 )
+ if (t_min0 * diff1 > t_max1 * diff0)
{
result = cast::apply(ps_strategy.apply(corner1, p0, p1));
return true;
}
// t_max0 < t_min1
- if ( t_max0 * diff1 < t_min1 * diff0 )
+ if (t_max0 * diff1 < t_min1 * diff0)
{
result = cast::apply(ps_strategy.apply(corner2, p0, p1));
return true;
@@ -489,7 +561,7 @@ private:
typedef compare_less_equal<ReturnType, true> less_equal;
// assert that the segment has non-negative slope
- BOOST_ASSERT( ( math::equals(geometry::get<0>(p0), geometry::get<0>(p1))
+ BOOST_GEOMETRY_ASSERT( ( math::equals(geometry::get<0>(p0), geometry::get<0>(p1))
&& geometry::get<1>(p0) < geometry::get<1>(p1))
||
( geometry::get<0>(p0) < geometry::get<0>(p1)
@@ -498,31 +570,31 @@ private:
ReturnType result(0);
- if ( check_right_left_of_box
- <
- less_equal
- >::apply(p0, p1,
- top_left, top_right, bottom_left, bottom_right,
- pp_strategy, ps_strategy, result) )
+ if (check_right_left_of_box
+ <
+ less_equal
+ >::apply(p0, p1,
+ top_left, top_right, bottom_left, bottom_right,
+ pp_strategy, ps_strategy, result))
{
return result;
}
- if ( check_above_below_of_box
- <
- less_equal
- >::apply(p0, p1,
- top_left, top_right, bottom_left, bottom_right,
- ps_strategy, result) )
+ if (check_above_below_of_box
+ <
+ less_equal
+ >::apply(p0, p1,
+ top_left, top_right, bottom_left, bottom_right,
+ ps_strategy, result))
{
return result;
}
- if ( check_generic_position::apply(p0, p1,
- bottom_left, top_right,
- bottom_left, top_right,
- top_left, bottom_right,
- ps_strategy, result) )
+ if (check_generic_position::apply(p0, p1,
+ bottom_left, top_right,
+ bottom_left, top_right,
+ top_left, bottom_right,
+ ps_strategy, result))
{
return result;
}
@@ -545,36 +617,36 @@ private:
typedef compare_less_equal<ReturnType, false> greater_equal;
// assert that the segment has negative slope
- BOOST_ASSERT( geometry::get<0>(p0) < geometry::get<0>(p1)
+ BOOST_GEOMETRY_ASSERT( geometry::get<0>(p0) < geometry::get<0>(p1)
&& geometry::get<1>(p0) > geometry::get<1>(p1) );
ReturnType result(0);
- if ( check_right_left_of_box
- <
- greater_equal
- >::apply(p0, p1,
- bottom_left, bottom_right, top_left, top_right,
- pp_strategy, ps_strategy, result) )
+ if (check_right_left_of_box
+ <
+ greater_equal
+ >::apply(p0, p1,
+ bottom_left, bottom_right, top_left, top_right,
+ pp_strategy, ps_strategy, result))
{
return result;
}
- if ( check_above_below_of_box
- <
- greater_equal
- >::apply(p1, p0,
- top_right, top_left, bottom_right, bottom_left,
- ps_strategy, result) )
+ if (check_above_below_of_box
+ <
+ greater_equal
+ >::apply(p1, p0,
+ top_right, top_left, bottom_right, bottom_left,
+ ps_strategy, result))
{
return result;
}
- if ( check_generic_position::apply(p0, p1,
- bottom_left, top_right,
- top_right, bottom_left,
- bottom_left, top_right,
- ps_strategy, result) )
+ if (check_generic_position::apply(p0, p1,
+ bottom_left, top_right,
+ top_right, bottom_left,
+ bottom_left, top_right,
+ ps_strategy, result))
{
return result;
}
@@ -593,10 +665,10 @@ public:
PPStrategy const& pp_strategy,
PSStrategy const& ps_strategy)
{
- BOOST_ASSERT( geometry::less<SegmentPoint>()(p0, p1) );
+ BOOST_GEOMETRY_ASSERT( geometry::less<SegmentPoint>()(p0, p1) );
- if ( geometry::get<0>(p0) < geometry::get<0>(p1)
- && geometry::get<1>(p0) > geometry::get<1>(p1) )
+ if (geometry::get<0>(p0) < geometry::get<0>(p1)
+ && geometry::get<1>(p0) > geometry::get<1>(p1))
{
return negative_slope_segment(p0, p1,
top_left, top_right,
@@ -670,7 +742,7 @@ public:
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
- if ( geometry::equals(p[0], p[1]) )
+ if (geometry::equals(p[0], p[1]))
{
typedef typename boost::mpl::if_
<
@@ -704,53 +776,34 @@ public:
detail::assign_box_corners(box, bottom_left, bottom_right,
top_left, top_right);
- pp_comparable_strategy c_pp_strategy =
- strategy::distance::services::get_comparable
- <
- PPStrategy
- >::apply(pp_strategy);
-
- ps_comparable_strategy c_ps_strategy =
- strategy::distance::services::get_comparable
- <
- PSStrategy
- >::apply(ps_strategy);
-
- comparable_return_type cd;
-
- if ( geometry::less<segment_point>()(p[0], p[1]) )
+ if (geometry::less<segment_point>()(p[0], p[1]))
{
- cd = segment_to_box_2D
+ return segment_to_box_2D
<
return_type,
segment_point,
box_point,
- pp_comparable_strategy,
- ps_comparable_strategy
+ PPStrategy,
+ PSStrategy
>::apply(p[0], p[1],
top_left, top_right, bottom_left, bottom_right,
- c_pp_strategy,
- c_ps_strategy);
+ pp_strategy,
+ ps_strategy);
}
else
{
- cd = segment_to_box_2D
+ return segment_to_box_2D
<
return_type,
segment_point,
box_point,
- pp_comparable_strategy,
- ps_comparable_strategy
+ PPStrategy,
+ PSStrategy
>::apply(p[1], p[0],
top_left, top_right, bottom_left, bottom_right,
- c_pp_strategy,
- c_ps_strategy);
+ pp_strategy,
+ ps_strategy);
}
-
- return strategy::distance::services::comparable_to_regular
- <
- ps_comparable_strategy, PSStrategy, Segment, Box
- >::apply( cd );
}
};
@@ -785,12 +838,32 @@ struct distance
{
assert_dimension_equal<Segment, Box>();
- typedef typename detail::distance::default_strategy
+ typedef typename boost::mpl::if_
<
- typename point_type<Segment>::type,
- typename point_type<Box>::type
+ boost::is_same
+ <
+ typename strategy::distance::services::comparable_type
+ <
+ Strategy
+ >::type,
+ Strategy
+ >,
+ typename strategy::distance::services::comparable_type
+ <
+ typename detail::distance::default_strategy
+ <
+ typename point_type<Segment>::type,
+ typename point_type<Box>::type
+ >::type
+ >::type,
+ typename detail::distance::default_strategy
+ <
+ typename point_type<Segment>::type,
+ typename point_type<Box>::type
+ >::type
>::type pp_strategy_type;
+
return detail::distance::segment_to_box
<
Segment,
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp
index 1ae22153ce..bdf056d76e 100644
--- a/3party/boost/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp
@@ -11,17 +11,23 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP
#include <algorithm>
+#include <iterator>
+
+#include <boost/core/addressof.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/util/condition.hpp>
+
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
-#include <boost/geometry/strategies/distance_comparable_to_regular.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
+
#include <boost/geometry/algorithms/dispatch/distance.hpp>
@@ -64,7 +70,7 @@ public:
apply(Segment1 const& segment1, Segment2 const& segment2,
Strategy const& strategy)
{
- if ( geometry::intersects(segment1, segment2) )
+ if (geometry::intersects(segment1, segment2))
{
return 0;
}
@@ -89,10 +95,25 @@ public:
d[2] = cstrategy.apply(p[0], q[0], q[1]);
d[3] = cstrategy.apply(p[1], q[0], q[1]);
- return strategy::distance::services::comparable_to_regular
- <
- comparable_strategy, Strategy, Segment1, Segment2
- >::apply( *std::min_element(d, d + 4) );
+ std::size_t imin = std::distance(boost::addressof(d[0]),
+ std::min_element(d, d + 4));
+
+ if (BOOST_GEOMETRY_CONDITION(is_comparable<Strategy>::value))
+ {
+ return d[imin];
+ }
+
+ switch (imin)
+ {
+ case 0:
+ return strategy.apply(q[0], p[0], p[1]);
+ case 1:
+ return strategy.apply(q[1], p[0], p[1]);
+ case 2:
+ return strategy.apply(p[0], q[0], q[1]);
+ default:
+ return strategy.apply(p[1], q[0], q[1]);
+ }
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/distance/single_to_multi.hpp b/3party/boost/boost/geometry/algorithms/detail/distance/single_to_multi.hpp
deleted file mode 100644
index 59cf172309..0000000000
--- a/3party/boost/boost/geometry/algorithms/detail/distance/single_to_multi.hpp
+++ /dev/null
@@ -1,526 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
-
-// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
-
-// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
-// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
-
-// Use, modification and distribution is subject to the Boost Software License,
-// 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_DISTANCE_SINGLE_TO_MULTI_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SINGLE_TO_MULTI_HPP
-
-#include <boost/numeric/conversion/bounds.hpp>
-#include <boost/range.hpp>
-
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/geometry_id.hpp>
-#include <boost/geometry/core/tag.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/geometries/concepts/check.hpp>
-
-#include <boost/geometry/strategies/distance.hpp>
-#include <boost/geometry/strategies/tags.hpp>
-
-#include <boost/geometry/util/select_coordinate_type.hpp>
-#include <boost/geometry/util/math.hpp>
-
-#include <boost/geometry/algorithms/not_implemented.hpp>
-#include <boost/geometry/algorithms/dispatch/distance.hpp>
-
-#include <boost/geometry/algorithms/detail/for_each_range.hpp>
-#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
-#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
-
-#include <boost/geometry/views/detail/range_type.hpp>
-
-#include <boost/geometry/algorithms/covered_by.hpp>
-#include <boost/geometry/algorithms/disjoint.hpp>
-#include <boost/geometry/algorithms/for_each.hpp>
-#include <boost/geometry/algorithms/within.hpp>
-
-#include <boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace distance
-{
-
-
-template<typename Geometry, typename MultiGeometry, typename Strategy>
-class distance_single_to_multi_generic
-{
-private:
- typedef typename strategy::distance::services::comparable_type
- <
- Strategy
- >::type comparable_strategy;
-
- typedef typename strategy::distance::services::return_type
- <
- comparable_strategy,
- typename point_type<Geometry>::type,
- typename point_type<MultiGeometry>::type
- >::type comparable_return_type;
-
-public:
- typedef typename strategy::distance::services::return_type
- <
- Strategy,
- typename point_type<Geometry>::type,
- typename point_type<MultiGeometry>::type
- >::type return_type;
-
- static inline return_type apply(Geometry const& geometry,
- MultiGeometry const& multi,
- Strategy const& strategy)
- {
- comparable_return_type min_cdist = comparable_return_type();
- bool first = true;
-
- comparable_strategy cstrategy =
- strategy::distance::services::get_comparable
- <
- Strategy
- >::apply(strategy);
-
- for (typename range_iterator<MultiGeometry const>::type it = boost::begin(multi);
- it != boost::end(multi);
- ++it, first = false)
- {
- comparable_return_type cdist = dispatch::distance
- <
- Geometry,
- typename range_value<MultiGeometry>::type,
- comparable_strategy
- >::apply(geometry, *it, cstrategy);
-
- if (first || cdist < min_cdist)
- {
- min_cdist = cdist;
- if ( geometry::math::equals(min_cdist, 0) )
- {
- break;
- }
- }
- }
-
- return strategy::distance::services::comparable_to_regular
- <
- comparable_strategy, Strategy, Geometry, MultiGeometry
- >::apply(min_cdist);
- }
-};
-
-
-
-template <typename MultiGeometry, typename Geometry, typename Strategy>
-struct distance_multi_to_single_generic
-{
- typedef typename strategy::distance::services::return_type
- <
- Strategy,
- typename point_type<MultiGeometry>::type,
- typename point_type<Geometry>::type
- >::type return_type;
-
- static inline return_type apply(MultiGeometry const& multi,
- Geometry const& geometry,
- Strategy const& strategy)
- {
- return distance_single_to_multi_generic
- <
- Geometry, MultiGeometry, Strategy
- >::apply(geometry, multi, strategy);
- }
-};
-
-
-
-
-}} // namespace detail::distance
-#endif // DOXYGEN_NO_DETAIL
-
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-namespace splitted_dispatch
-{
-
-
-template
-<
- typename Geometry,
- typename MultiGeometry,
- typename Strategy,
- typename GeometryTag,
- typename MultiGeometryTag,
- typename StrategyTag
->
-struct distance_single_to_multi
- : not_implemented<Geometry, MultiGeometry>
-{};
-
-
-
-template<typename Point, typename MultiPoint, typename Strategy>
-struct distance_single_to_multi
- <
- Point, MultiPoint, Strategy,
- point_tag, multi_point_tag,
- strategy_tag_distance_point_point
- > : detail::distance::distance_single_to_multi_generic
- <
- Point, MultiPoint, Strategy
- >
-{};
-
-
-
-template<typename Point, typename MultiLinestring, typename Strategy>
-struct distance_single_to_multi
- <
- Point, MultiLinestring, Strategy,
- point_tag, multi_linestring_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::distance_single_to_multi_generic
- <
- Point, MultiLinestring, Strategy
- >
-{};
-
-
-
-template<typename Point, typename MultiPolygon, typename Strategy>
-struct distance_single_to_multi
- <
- Point, MultiPolygon, Strategy,
- point_tag, multi_polygon_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::distance_single_to_multi_generic
- <
- Point, MultiPolygon, Strategy
- >
-{};
-
-
-
-template<typename Linestring, typename MultiLinestring, typename Strategy>
-struct distance_single_to_multi
- <
- Linestring, MultiLinestring, Strategy,
- linestring_tag, multi_linestring_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- Linestring, MultiLinestring, Strategy
- >
-{};
-
-
-
-template <typename Linestring, typename MultiPolygon, typename Strategy>
-struct distance_single_to_multi
- <
- Linestring, MultiPolygon, Strategy,
- linestring_tag, multi_polygon_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- Linestring, MultiPolygon, Strategy
- >
-{};
-
-
-
-template <typename Polygon, typename MultiPoint, typename Strategy>
-struct distance_single_to_multi
- <
- Polygon, MultiPoint, Strategy,
- polygon_tag, multi_point_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::distance_single_to_multi_generic
- <
- Polygon, MultiPoint, Strategy
- >
-{};
-
-
-
-template <typename Polygon, typename MultiLinestring, typename Strategy>
-struct distance_single_to_multi
- <
- Polygon, MultiLinestring, Strategy,
- polygon_tag, multi_linestring_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- Polygon, MultiLinestring, Strategy
- >
-{};
-
-
-
-template <typename Polygon, typename MultiPolygon, typename Strategy>
-struct distance_single_to_multi
- <
- Polygon, MultiPolygon, Strategy,
- polygon_tag, multi_polygon_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- Polygon, MultiPolygon, Strategy
- >
-{};
-
-
-
-template <typename MultiLinestring, typename Ring, typename Strategy>
-struct distance_single_to_multi
- <
- MultiLinestring, Ring, Strategy,
- multi_linestring_tag, ring_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- MultiLinestring, Ring, Strategy
- >
-{};
-
-
-template <typename MultiPolygon, typename Ring, typename Strategy>
-struct distance_single_to_multi
- <
- MultiPolygon, Ring, Strategy,
- multi_polygon_tag, ring_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- MultiPolygon, Ring, Strategy
- >
-{};
-
-
-
-template
-<
- typename MultiGeometry,
- typename Geometry,
- typename Strategy,
- typename MultiGeometryTag,
- typename GeometryTag,
- typename StrategyTag
->
-struct distance_multi_to_single
- : not_implemented<MultiGeometry, Geometry>
-{};
-
-
-
-template
-<
- typename MultiPoint,
- typename Segment,
- typename Strategy
->
-struct distance_multi_to_single
- <
- MultiPoint, Segment, Strategy,
- multi_point_tag, segment_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::distance_multi_to_single_generic
- <
- MultiPoint, Segment, Strategy
- >
-{};
-
-
-
-template
-<
- typename MultiPoint,
- typename Ring,
- typename Strategy
->
-struct distance_multi_to_single
- <
- MultiPoint, Ring, Strategy,
- multi_point_tag, ring_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::distance_multi_to_single_generic
- <
- MultiPoint, Ring, Strategy
- >
-{};
-
-
-
-template
-<
- typename MultiPoint,
- typename Box,
- typename Strategy
->
-struct distance_multi_to_single
- <
- MultiPoint, Box, Strategy,
- multi_point_tag, box_tag,
- strategy_tag_distance_point_box
- > : detail::distance::distance_multi_to_single_generic
- <
- MultiPoint, Box, Strategy
- >
-{};
-
-
-template <typename MultiLinestring, typename Segment, typename Strategy>
-struct distance_multi_to_single
- <
- MultiLinestring, Segment, Strategy,
- multi_linestring_tag, segment_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::distance_multi_to_single_generic
- <
- MultiLinestring, Segment, Strategy
- >
-{};
-
-
-template <typename MultiLinestring, typename Ring, typename Strategy>
-struct distance_multi_to_single
- <
- MultiLinestring, Ring, Strategy,
- multi_linestring_tag, ring_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- MultiLinestring, Ring, Strategy
- >
-{};
-
-
-template <typename MultiLinestring, typename Box, typename Strategy>
-struct distance_multi_to_single
- <
- MultiLinestring, Box, Strategy,
- multi_linestring_tag, box_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::distance_multi_to_single_generic
- <
- MultiLinestring, Box, Strategy
- >
-{};
-
-
-
-template <typename MultiPolygon, typename Segment, typename Strategy>
-struct distance_multi_to_single
- <
- MultiPolygon, Segment, Strategy,
- multi_polygon_tag, segment_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::distance_multi_to_single_generic
- <
- MultiPolygon, Segment, Strategy
- >
-{};
-
-
-template <typename MultiPolygon, typename Ring, typename Strategy>
-struct distance_multi_to_single
- <
- MultiPolygon, Ring, Strategy,
- multi_polygon_tag, ring_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::geometry_to_geometry_rtree
- <
- MultiPolygon, Ring, Strategy
- >
-{};
-
-
-template <typename MultiPolygon, typename Box, typename Strategy>
-struct distance_multi_to_single
- <
- MultiPolygon, Box, Strategy,
- multi_polygon_tag, box_tag,
- strategy_tag_distance_point_segment
- > : detail::distance::distance_multi_to_single_generic
- <
- MultiPolygon, Box, Strategy
- >
-{};
-
-
-} // namespace splitted_dispatch
-
-
-template
-<
- typename Geometry,
- typename MultiGeometry,
- typename Strategy,
- typename GeometryTag,
- typename StrategyTag
->
-struct distance
- <
- Geometry, MultiGeometry, Strategy, GeometryTag, multi_tag,
- StrategyTag, false
- > : splitted_dispatch::distance_single_to_multi
- <
- Geometry, MultiGeometry, Strategy,
- GeometryTag, typename tag<MultiGeometry>::type,
- StrategyTag
- >
-{};
-
-
-
-template
-<
- typename MultiGeometry,
- typename Geometry,
- typename Strategy,
- typename GeometryTag,
- typename StrategyTag
->
-struct distance
- <
- MultiGeometry, Geometry, Strategy, multi_tag, GeometryTag,
- StrategyTag, false
- > : splitted_dispatch::distance_multi_to_single
- <
- MultiGeometry, Geometry, Strategy,
- typename tag<MultiGeometry>::type, GeometryTag,
- StrategyTag
- >
-{};
-
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-}} // namespace boost::geometry
-
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SINGLE_TO_MULTI_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/box.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/box.hpp
new file mode 100644
index 0000000000..0b3f177093
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/box.hpp
@@ -0,0 +1,95 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ENVELOPE_BOX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+struct envelope_box_on_spheroid
+{
+ template<typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ BoxIn box_in_normalized = detail::return_normalized<BoxIn>(box_in);
+
+ geometry::transform(box_in_normalized, mbr);
+ }
+};
+
+
+template <typename CSTag>
+struct envelope_box
+{
+ template<typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ geometry::convert(box_in, mbr);
+ }
+};
+
+template <>
+struct envelope_box<spherical_equatorial_tag>
+ : envelope_box_on_spheroid
+{};
+
+template <>
+struct envelope_box<geographic_tag>
+ : envelope_box_on_spheroid
+{};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Box>
+struct envelope<Box, box_tag>
+ : detail::envelope::envelope_box<typename cs_tag<Box>::type>
+{};
+
+
+} // namespace dispatch
+#endif
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/implementation.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/implementation.hpp
new file mode 100644
index 0000000000..c88adac7a6
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/implementation.hpp
@@ -0,0 +1,104 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ENVELOPE_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_HPP
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/expand.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/linestring.hpp>
+#include <boost/geometry/algorithms/detail/envelope/multilinestring.hpp>
+#include <boost/geometry/algorithms/detail/envelope/multipoint.hpp>
+#include <boost/geometry/algorithms/detail/envelope/point.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+struct exterior_ring_expand_policy
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& mbr, Geometry const& geometry)
+ {
+ Box ring_mbr;
+ envelope_range<>::apply(exterior_ring(geometry), ring_mbr);
+ geometry::expand(mbr, ring_mbr);
+ }
+};
+
+
+struct envelope_polygon
+{
+ template <typename Polygon, typename Box>
+ static inline void apply(Polygon const& poly, Box& mbr)
+ {
+ // For polygon, inspecting outer ring is sufficient
+ envelope_range<>::apply(exterior_ring(poly), mbr);
+ }
+
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Ring>
+struct envelope<Ring, ring_tag>
+ : detail::envelope::envelope_range<>
+{};
+
+
+template <typename Polygon>
+struct envelope<Polygon, polygon_tag>
+ : detail::envelope::envelope_polygon
+{};
+
+
+template <typename MultiPolygon>
+struct envelope<MultiPolygon, multi_polygon_tag>
+ : detail::envelope::envelope_range
+ <
+ detail::envelope::exterior_ring_expand_policy
+ >
+{};
+
+
+} // namespace dispatch
+#endif
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/interface.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/interface.hpp
new file mode 100644
index 0000000000..3c1b2b9fe7
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/interface.hpp
@@ -0,0 +1,126 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ENVELOPE_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct envelope
+{
+ template <typename Box>
+ static inline void apply(Geometry const& geometry, Box& box)
+ {
+ concept::check<Geometry const>();
+ concept::check<Box>();
+
+ dispatch::envelope<Geometry>::apply(geometry, box);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Box>
+ struct visitor: boost::static_visitor<void>
+ {
+ Box& m_box;
+
+ visitor(Box& box): m_box(box) {}
+
+ template <typename Geometry>
+ void operator()(Geometry const& geometry) const
+ {
+ envelope<Geometry>::apply(geometry, m_box);
+ }
+ };
+
+ template <typename Box>
+ static inline void
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+ Box& box)
+ {
+ boost::apply_visitor(visitor<Box>(box), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/*!
+\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)
+{
+ resolve_variant::envelope<Geometry>::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)
+{
+ Box mbr;
+ resolve_variant::envelope<Geometry>::apply(geometry, mbr);
+ return mbr;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp
new file mode 100644
index 0000000000..4bd9177961
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp
@@ -0,0 +1,77 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace envelope
+{
+
+
+struct intersects_antimeridian
+{
+ template <typename Units, typename CoordinateType>
+ static inline bool apply(CoordinateType const& lon1,
+ CoordinateType const& lat1,
+ CoordinateType const& lon2,
+ CoordinateType const& lat2)
+ {
+ typedef math::detail::constants_on_spheroid
+ <
+ CoordinateType, Units
+ > constants;
+
+ return
+ math::equals(math::abs(lat1), constants::max_latitude())
+ ||
+ math::equals(math::abs(lat2), constants::max_latitude())
+ ||
+ math::larger(math::abs(lon1 - lon2), constants::half_period());
+ }
+
+ template <typename Segment>
+ static inline bool apply(Segment const& segment)
+ {
+ return apply(detail::indexed_point_view<Segment, 0>(segment),
+ detail::indexed_point_view<Segment, 1>(segment));
+ }
+
+ template <typename Point>
+ static inline bool apply(Point const& p1, Point const& p2)
+ {
+ Point p1_normalized = detail::return_normalized<Point>(p1);
+ Point p2_normalized = detail::return_normalized<Point>(p2);
+
+ return apply
+ <
+ typename coordinate_system<Point>::type::units
+ >(geometry::get<0>(p1_normalized),
+ geometry::get<1>(p1_normalized),
+ geometry::get<0>(p2_normalized),
+ geometry::get<1>(p2_normalized));
+ }
+};
+
+
+}} // namespace detail::envelope
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/linestring.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/linestring.hpp
new file mode 100644
index 0000000000..379bd78902
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/linestring.hpp
@@ -0,0 +1,182 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ENVELOPE_LINESTRING_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINESTRING_HPP
+
+#include <iterator>
+#include <vector>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+struct envelope_linear_on_spheroid
+{
+ template <typename Units, typename Longitude, typename OutputIterator>
+ static inline OutputIterator push_interval(Longitude const& lon1,
+ Longitude const& lon2,
+ OutputIterator oit)
+ {
+ typedef longitude_interval<Longitude> interval_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ Longitude, Units
+ > constants;
+
+ BOOST_GEOMETRY_ASSERT(! math::larger(lon1, lon2));
+ BOOST_GEOMETRY_ASSERT(! math::larger(lon1, constants::max_longitude()));
+
+ if (math::larger(lon2, constants::max_longitude()))
+ {
+ *oit++ = interval_type(lon1, constants::max_longitude());
+ *oit++ = interval_type(constants::min_longitude(),
+ lon2 - constants::period());
+ }
+ else
+ {
+ *oit++ = interval_type(lon1, lon2);
+ }
+ return oit;
+ }
+
+ template <typename Linear, typename Box>
+ static inline void apply(Linear const& linear, Box& mbr)
+ {
+ typedef typename coordinate_type<Box>::type box_coordinate_type;
+ typedef longitude_interval<box_coordinate_type> interval_type;
+
+ typedef typename geometry::segment_iterator
+ <
+ Linear const
+ > iterator_type;
+
+ BOOST_GEOMETRY_ASSERT(! geometry::is_empty(linear));
+
+ std::vector<interval_type> longitude_intervals;
+ std::back_insert_iterator
+ <
+ std::vector<interval_type>
+ > oit(longitude_intervals);
+
+ box_coordinate_type lat_min = 0, lat_max = 0;
+ bool first = true;
+ for (iterator_type seg_it = geometry::segments_begin(linear);
+ seg_it != geometry::segments_end(linear);
+ ++seg_it, first = false)
+ {
+ Box segment_mbr;
+ dispatch::envelope
+ <
+ typename std::iterator_traits<iterator_type>::value_type
+ >::apply(*seg_it, segment_mbr);
+
+ oit = push_interval
+ <
+ typename coordinate_system<Box>::type::units
+ >(geometry::get<min_corner, 0>(segment_mbr),
+ geometry::get<max_corner, 0>(segment_mbr),
+ oit);
+
+ if (first)
+ {
+ lat_min = geometry::get<min_corner, 1>(segment_mbr);
+ lat_max = geometry::get<max_corner, 1>(segment_mbr);
+ }
+
+ // update min and max latitude, if needed
+ if (math::smaller(geometry::get<min_corner, 1>(segment_mbr),
+ lat_min))
+ {
+ lat_min = geometry::get<min_corner, 1>(segment_mbr);
+ }
+
+ if (math::larger(geometry::get<max_corner, 1>(segment_mbr),
+ lat_max))
+ {
+ lat_max = geometry::get<max_corner, 1>(segment_mbr);
+ }
+ }
+
+ box_coordinate_type lon_min = 0, lon_max = 0;
+ envelope_range_of_longitudes
+ <
+ typename coordinate_system<Box>::type::units
+ >::apply(longitude_intervals, lon_min, lon_max);
+
+ assign_values(mbr, lon_min, lat_min, lon_max, lat_max);
+ }
+};
+
+
+template <typename CSTag>
+struct envelope_linestring
+ : envelope_range<>
+{};
+
+template <>
+struct envelope_linestring<spherical_equatorial_tag>
+ : envelope_linear_on_spheroid
+{};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Linestring>
+struct envelope<Linestring, linestring_tag>
+ : detail::envelope::envelope_linestring<typename cs_tag<Linestring>::type>
+{};
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINESTRING_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/multilinestring.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/multilinestring.hpp
new file mode 100644
index 0000000000..fc15baa471
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/multilinestring.hpp
@@ -0,0 +1,86 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ENVELOPE_MULTILINESTRING_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTILINESTRING_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/expand.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/linestring.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+struct envelope_range_expand_policy
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& mbr, Geometry const& geometry)
+ {
+ Box mbr2;
+ envelope_range<>::apply(geometry, mbr2);
+ geometry::expand(mbr, mbr2);
+ }
+};
+
+
+template <typename CSTag>
+struct envelope_multilinestring
+ : envelope_range<envelope_range_expand_policy>
+{};
+
+template <>
+struct envelope_multilinestring<spherical_equatorial_tag>
+ : envelope_linear_on_spheroid
+{};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiLinestring>
+struct envelope<MultiLinestring, multi_linestring_tag>
+ : detail::envelope::envelope_multilinestring
+ <
+ typename cs_tag<MultiLinestring>::type
+ >
+{};
+
+
+} // namespace dispatch
+#endif
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTILINESTRING_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/multipoint.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/multipoint.hpp
new file mode 100644
index 0000000000..3574e54202
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/multipoint.hpp
@@ -0,0 +1,348 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
+
+#include <algorithm>
+#include <utility>
+#include <vector>
+
+#include <boost/algorithm/minmax_element.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+class envelope_multipoint_on_spheroid
+{
+private:
+ template <std::size_t Dimension>
+ struct coordinate_less
+ {
+ template <typename Point>
+ inline bool operator()(Point const& point1, Point const& point2) const
+ {
+ return math::smaller(geometry::get<Dimension>(point1),
+ geometry::get<Dimension>(point2));
+ }
+ };
+
+ template <typename Constants, typename MultiPoint, typename OutputIterator>
+ static inline void analyze_point_coordinates(MultiPoint const& multipoint,
+ bool& has_south_pole,
+ bool& has_north_pole,
+ OutputIterator oit)
+ {
+ typedef typename boost::range_value<MultiPoint>::type point_type;
+ typedef typename boost::range_iterator
+ <
+ MultiPoint const
+ >::type iterator_type;
+
+ // analyze point coordinates:
+ // (1) normalize point coordinates
+ // (2) check if any point is the north or the south pole
+ // (3) put all non-pole points in a container
+ //
+ // notice that at this point in the algorithm, we have at
+ // least two points on the spheroid
+ has_south_pole = false;
+ has_north_pole = false;
+
+ for (iterator_type it = boost::begin(multipoint);
+ it != boost::end(multipoint);
+ ++it)
+ {
+ point_type point = detail::return_normalized<point_type>(*it);
+
+ if (math::equals(geometry::get<1>(point),
+ Constants::min_latitude()))
+ {
+ has_south_pole = true;
+ }
+ else if (math::equals(geometry::get<1>(point),
+ Constants::max_latitude()))
+ {
+ has_north_pole = true;
+ }
+ else
+ {
+ *oit++ = point;
+ }
+ }
+ }
+
+ template <typename SortedRange, typename Value>
+ static inline Value maximum_gap(SortedRange const& sorted_range,
+ Value& max_gap_left,
+ Value& max_gap_right)
+ {
+ typedef typename boost::range_iterator
+ <
+ SortedRange const
+ >::type iterator_type;
+
+ iterator_type it1 = boost::begin(sorted_range), it2 = it1;
+ ++it2;
+ max_gap_left = geometry::get<0>(*it1);
+ max_gap_right = geometry::get<0>(*it2);
+
+ Value max_gap = max_gap_right - max_gap_left;
+ for (++it1, ++it2; it2 != boost::end(sorted_range); ++it1, ++it2)
+ {
+ Value gap = geometry::get<0>(*it2) - geometry::get<0>(*it1);
+ if (math::larger(gap, max_gap))
+ {
+ max_gap_left = geometry::get<0>(*it1);
+ max_gap_right = geometry::get<0>(*it2);
+ max_gap = gap;
+ }
+ }
+
+ return max_gap;
+ }
+
+ template
+ <
+ typename Constants,
+ typename PointRange,
+ typename LongitudeLess,
+ typename CoordinateType
+ >
+ static inline void get_min_max_longitudes(PointRange& range,
+ LongitudeLess const& lon_less,
+ CoordinateType& lon_min,
+ CoordinateType& lon_max)
+ {
+ typedef typename boost::range_iterator
+ <
+ PointRange const
+ >::type iterator_type;
+
+ // compute min and max longitude values
+ std::pair<iterator_type, iterator_type> min_max_longitudes
+ = boost::minmax_element(boost::begin(range),
+ boost::end(range),
+ lon_less);
+
+ lon_min = geometry::get<0>(*min_max_longitudes.first);
+ lon_max = geometry::get<0>(*min_max_longitudes.second);
+
+ // if the longitude span is "large" compute the true maximum gap
+ if (math::larger(lon_max - lon_min, Constants::half_period()))
+ {
+ std::sort(boost::begin(range), boost::end(range), lon_less);
+
+ CoordinateType max_gap_left = 0, max_gap_right = 0;
+ CoordinateType max_gap
+ = maximum_gap(range, max_gap_left, max_gap_right);
+
+ CoordinateType complement_gap
+ = Constants::period() + lon_min - lon_max;
+
+ if (math::larger(max_gap, complement_gap))
+ {
+ lon_min = max_gap_right;
+ lon_max = max_gap_left + Constants::period();
+ }
+ }
+ }
+
+ template
+ <
+ typename Constants,
+ typename Iterator,
+ typename LatitudeLess,
+ typename CoordinateType
+ >
+ static inline void get_min_max_latitudes(Iterator const first,
+ Iterator const last,
+ LatitudeLess const& lat_less,
+ bool has_south_pole,
+ bool has_north_pole,
+ CoordinateType& lat_min,
+ CoordinateType& lat_max)
+ {
+ if (has_south_pole && has_north_pole)
+ {
+ lat_min = Constants::min_latitude();
+ lat_max = Constants::max_latitude();
+ }
+ else if (has_south_pole)
+ {
+ lat_min = Constants::min_latitude();
+ lat_max
+ = geometry::get<1>(*std::max_element(first, last, lat_less));
+ }
+ else if (has_north_pole)
+ {
+ lat_min
+ = geometry::get<1>(*std::min_element(first, last, lat_less));
+ lat_max = Constants::max_latitude();
+ }
+ else
+ {
+ std::pair<Iterator, Iterator> min_max_latitudes
+ = boost::minmax_element(first, last, lat_less);
+
+ lat_min = geometry::get<1>(*min_max_latitudes.first);
+ lat_max = geometry::get<1>(*min_max_latitudes.second);
+ }
+ }
+
+public:
+ template <typename MultiPoint, typename Box>
+ static inline void apply(MultiPoint const& multipoint, Box& mbr)
+ {
+ typedef typename point_type<MultiPoint>::type point_type;
+ typedef typename coordinate_type<MultiPoint>::type coordinate_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ coordinate_type,
+ typename coordinate_system<MultiPoint>::type::units
+ > constants;
+
+
+ if (boost::empty(multipoint))
+ {
+ return;
+ }
+
+ if (boost::size(multipoint) == 1)
+ {
+ return dispatch::envelope
+ <
+ typename boost::range_value<MultiPoint>::type
+ >::apply(range::front(multipoint), mbr);
+ }
+
+ // analyze the points and put the non-pole ones in the
+ // points vector
+ std::vector<point_type> points;
+ bool has_north_pole = false, has_south_pole = false;
+
+ analyze_point_coordinates<constants>(multipoint,
+ has_south_pole, has_north_pole,
+ std::back_inserter(points));
+
+ coordinate_type lon_min, lat_min, lon_max, lat_max;
+ if (points.size() == 1)
+ {
+ // we have one non-pole point and at least one pole point
+ lon_min = geometry::get<0>(range::front(points));
+ lon_max = geometry::get<0>(range::front(points));
+ lat_min = has_south_pole
+ ? constants::min_latitude()
+ : constants::max_latitude();
+ lat_max = has_north_pole
+ ? constants::max_latitude()
+ : constants::min_latitude();
+ }
+ else if (points.empty())
+ {
+ // all points are pole points
+ BOOST_GEOMETRY_ASSERT(has_south_pole || has_north_pole);
+ lon_min = coordinate_type(0);
+ lon_max = coordinate_type(0);
+ lat_min = has_south_pole
+ ? constants::min_latitude()
+ : constants::max_latitude();
+ lat_max = (has_north_pole)
+ ? constants::max_latitude()
+ : constants::min_latitude();
+ }
+ else
+ {
+ get_min_max_longitudes<constants>(points,
+ coordinate_less<0>(),
+ lon_min,
+ lon_max);
+
+ get_min_max_latitudes<constants>(points.begin(),
+ points.end(),
+ coordinate_less<1>(),
+ has_south_pole,
+ has_north_pole,
+ lat_min,
+ lat_max);
+ }
+
+ typename helper_geometry
+ <
+ Box,
+ coordinate_type,
+ typename coordinate_system<MultiPoint>::type::units
+ >::type helper_mbr;
+
+ assign_values(helper_mbr, lon_min, lat_min, lon_max, lat_max);
+
+ geometry::transform(helper_mbr, mbr);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPoint, typename CSTag>
+struct envelope<MultiPoint, multi_point_tag, CSTag>
+ : detail::envelope::envelope_range<>
+{};
+
+template <typename MultiPoint>
+struct envelope<MultiPoint, multi_point_tag, spherical_equatorial_tag>
+ : detail::envelope::envelope_multipoint_on_spheroid
+{};
+
+template <typename MultiPoint>
+struct envelope<MultiPoint, multi_point_tag, geographic_tag>
+ : detail::envelope::envelope_multipoint_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/point.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/point.hpp
new file mode 100644
index 0000000000..9e9b01d223
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/point.hpp
@@ -0,0 +1,99 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ENVELOPE_POINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+struct envelope_point_on_spheroid
+{
+ template<typename Point, typename Box>
+ static inline void apply(Point const& point, Box& mbr)
+ {
+ Point normalized_point = detail::return_normalized<Point>(point);
+
+ typename point_type<Box>::type box_point;
+
+ // transform input point to a point of the same type as box's point
+ geometry::transform(normalized_point, box_point);
+
+ geometry::convert(box_point, mbr);
+ }
+};
+
+
+template <typename CSTag>
+struct envelope_one_point
+{
+ template<typename Point, typename Box>
+ static inline void apply(Point const& point, Box& mbr)
+ {
+ geometry::convert(point, mbr);
+ }
+};
+
+template <>
+struct envelope_one_point<spherical_equatorial_tag>
+ : envelope_point_on_spheroid
+{};
+
+template <>
+struct envelope_one_point<geographic_tag>
+ : envelope_point_on_spheroid
+{};
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Point>
+struct envelope<Point, point_tag>
+ : detail::envelope::envelope_one_point<typename cs_tag<Point>::type>
+{};
+
+
+} // namespace dispatch
+#endif
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/range.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/range.hpp
new file mode 100644
index 0000000000..b2023f338a
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/range.hpp
@@ -0,0 +1,93 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ENVELOPE_RANGE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_HPP
+
+#include <boost/range.hpp>
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/algorithms/expand.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+struct default_expand_policy
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& mbr, Geometry const& geometry)
+ {
+ geometry::expand(mbr, geometry);
+ }
+};
+
+
+template <typename ExpandPolicy, typename Iterator, typename Box>
+inline void envelope_iterators(Iterator first, Iterator last, Box& mbr)
+{
+ for (Iterator it = first; it != last; ++it)
+ {
+ ExpandPolicy::apply(mbr, *it);
+ }
+}
+
+
+template <typename ExpandPolicy = default_expand_policy>
+struct envelope_range
+{
+ /// Calculate envelope of range using a strategy
+ template <typename Range, typename Box>
+ static inline void apply(Range const& range, Box& mbr)
+ {
+ typename boost::range_iterator<Range const>::type it
+ = boost::begin(range);
+
+ if (it != boost::end(range))
+ {
+ // initialize box with first element in range
+ dispatch::envelope
+ <
+ typename boost::range_value<Range>::type
+ >::apply(*it, mbr);
+
+ // consider now the remaining elements in the range (if any)
+ ++it;
+ envelope_iterators
+ <
+ ExpandPolicy
+ >(it, boost::end(range), mbr);
+ }
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
new file mode 100644
index 0000000000..90a1b099bc
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
@@ -0,0 +1,242 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_OF_BOXES_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_OF_BOXES_HPP
+
+#include <cstddef>
+
+#include <algorithm>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/detail/max_interval_gap.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template <typename T>
+class longitude_interval
+{
+ typedef T const& reference_type;
+
+public:
+ typedef T value_type;
+ typedef T difference_type;
+
+ longitude_interval(T const& left, T const& right)
+ {
+ m_end[0] = left;
+ m_end[1] = right;
+ }
+
+ template <std::size_t Index>
+ reference_type get() const
+ {
+ return m_end[Index];
+ }
+
+ difference_type length() const
+ {
+ return get<1>() - get<0>();
+ }
+
+private:
+ T m_end[2];
+};
+
+
+template <typename Units>
+struct envelope_range_of_longitudes
+{
+ template <std::size_t Index>
+ struct longitude_less
+ {
+ template <typename Interval>
+ inline bool operator()(Interval const& i1, Interval const& i2) const
+ {
+ return math::smaller(i1.template get<Index>(),
+ i2.template get<Index>());
+ }
+ };
+
+ template <typename RangeOfLongitudeIntervals, typename Longitude>
+ static inline void apply(RangeOfLongitudeIntervals const& range,
+ Longitude& lon_min, Longitude& lon_max)
+ {
+ typedef typename math::detail::constants_on_spheroid
+ <
+ Longitude, Units
+ > constants;
+
+ Longitude const zero = 0;
+ Longitude const period = constants::period();
+ Longitude const min_longitude = constants::min_longitude();
+ Longitude const max_longitude = constants::max_longitude();
+
+ lon_min = lon_max = zero;
+
+ // the range of longitude intervals can be empty if all input boxes
+ // degenerate to the north or south pole (or combination of the two)
+ // in this case the initialization values for lon_min and
+ // lon_max are valid choices
+ if (! boost::empty(range))
+ {
+ lon_min = std::min_element(boost::begin(range),
+ boost::end(range),
+ longitude_less<0>())->template get<0>();
+ lon_max = std::max_element(boost::begin(range),
+ boost::end(range),
+ longitude_less<1>())->template get<1>();
+
+ if (math::larger(lon_max - lon_min, constants::half_period()))
+ {
+ Longitude max_gap_left, max_gap_right;
+ Longitude max_gap = geometry::maximum_gap(range,
+ max_gap_left,
+ max_gap_right);
+
+ BOOST_GEOMETRY_ASSERT(! math::larger(lon_min, lon_max));
+ BOOST_GEOMETRY_ASSERT(! math::larger(lon_max, max_longitude));
+ BOOST_GEOMETRY_ASSERT(! math::smaller(lon_min, min_longitude));
+
+ BOOST_GEOMETRY_ASSERT(! math::larger(max_gap_left, max_gap_right));
+ BOOST_GEOMETRY_ASSERT(! math::larger(max_gap_right, max_longitude));
+ BOOST_GEOMETRY_ASSERT(! math::smaller(max_gap_left, min_longitude));
+
+ if (math::larger(max_gap, zero))
+ {
+ Longitude wrapped_gap = period + lon_min - lon_max;
+ if (math::larger(max_gap, wrapped_gap))
+ {
+ lon_min = max_gap_right;
+ lon_max = max_gap_left + period;
+ }
+ }
+ }
+ }
+ }
+};
+
+
+struct envelope_range_of_boxes
+{
+ template <std::size_t Index>
+ struct latitude_less
+ {
+ template <typename Box>
+ inline bool operator()(Box const& box1, Box const& box2) const
+ {
+ return math::smaller(geometry::get<Index, 1>(box1),
+ geometry::get<Index, 1>(box2));
+ }
+ };
+
+ template <typename RangeOfBoxes, typename Box>
+ static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
+ {
+ // boxes in the range are assumed to be normalized already
+
+ typedef typename boost::range_value<RangeOfBoxes>::type box_type;
+ typedef typename coordinate_type<box_type>::type coordinate_type;
+ typedef typename coordinate_system<box_type>::type::units units_type;
+ typedef typename boost::range_iterator
+ <
+ RangeOfBoxes const
+ >::type iterator_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ coordinate_type, units_type
+ > constants;
+
+ typedef longitude_interval<coordinate_type> interval_type;
+ typedef std::vector<interval_type> interval_range_type;
+
+ BOOST_GEOMETRY_ASSERT(! boost::empty(range_of_boxes));
+
+ iterator_type it_min = std::min_element(boost::begin(range_of_boxes),
+ boost::end(range_of_boxes),
+ latitude_less<min_corner>());
+ iterator_type it_max = std::max_element(boost::begin(range_of_boxes),
+ boost::end(range_of_boxes),
+ latitude_less<max_corner>());
+
+ coordinate_type const min_longitude = constants::min_longitude();
+ coordinate_type const max_longitude = constants::max_longitude();
+ coordinate_type const period = constants::period();
+
+ interval_range_type intervals;
+ for (iterator_type it = boost::begin(range_of_boxes);
+ it != boost::end(range_of_boxes);
+ ++it)
+ {
+ coordinate_type lat_min = geometry::get<min_corner, 1>(*it);
+ coordinate_type lat_max = geometry::get<max_corner, 1>(*it);
+ if (math::equals(lat_min, constants::max_latitude())
+ || math::equals(lat_max, constants::min_latitude()))
+ {
+ // if the box degenerates to the south or north pole
+ // just ignore it
+ continue;
+ }
+
+ coordinate_type lon_left = geometry::get<min_corner, 0>(*it);
+ coordinate_type lon_right = geometry::get<max_corner, 0>(*it);
+
+ if (math::larger(lon_right, max_longitude))
+ {
+ intervals.push_back(interval_type(lon_left, max_longitude));
+ intervals.push_back
+ (interval_type(min_longitude, lon_right - period));
+ }
+ else
+ {
+ intervals.push_back(interval_type(lon_left, lon_right));
+ }
+ }
+
+ coordinate_type lon_min(0), lon_max(0);
+ envelope_range_of_longitudes
+ <
+ units_type
+ >::apply(intervals, lon_min, lon_max);
+
+ // do not convert units; conversion will be performed at a
+ // higher level
+ assign_values(mbr,
+ lon_min,
+ geometry::get<min_corner, 1>(*it_min),
+ lon_max,
+ geometry::get<max_corner, 1>(*it_max));
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_OF_BOXES_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/envelope/segment.hpp b/3party/boost/boost/geometry/algorithms/detail/envelope/segment.hpp
new file mode 100644
index 0000000000..9b53c84f9d
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/envelope/segment.hpp
@@ -0,0 +1,339 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ENVELOPE_SEGMENT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
+
+#include <utility>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/point.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+// Computes the MBR of a segment given by (lon1, lat1) and (lon2,
+// lat2), and with azimuths a1 and a2 at the two endpoints of the
+// segment.
+// It is assumed that the spherical coordinates of the segment are
+// normalized and in radians.
+// The longitudes and latitudes of the endpoints are overridden by
+// those of the box.
+class compute_mbr_of_segment
+{
+private:
+ // computes the azimuths of the segment with endpoints (lon1, lat1)
+ // and (lon2, lat2)
+ template <typename CalculationType>
+ static inline void azimuths(CalculationType const& lon1,
+ CalculationType const& lat1,
+ CalculationType const& lon2,
+ CalculationType const& lat2,
+ CalculationType& a1,
+ CalculationType& a2)
+ {
+ BOOST_GEOMETRY_ASSERT(math::smaller(lon1, lon2));
+
+ CalculationType dlon = lon2 - lon1;
+ CalculationType sin_dlon = sin(dlon);
+ CalculationType cos_dlon = cos(dlon);
+ CalculationType cos_lat1 = cos(lat1);
+ CalculationType cos_lat2 = cos(lat2);
+ CalculationType sin_lat1 = sin(lat1);
+ CalculationType sin_lat2 = sin(lat2);
+
+ a1 = atan2(sin_dlon * cos_lat2,
+ cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon);
+
+ a2 = atan2(-sin_dlon * cos_lat1,
+ cos_lat2 * sin_lat1 - sin_lat2 * cos_lat1 * cos_dlon);
+ a2 += math::pi<CalculationType>();
+ }
+
+ template <typename CalculationType>
+ static inline void swap(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2)
+ {
+ std::swap(lon1, lon2);
+ std::swap(lat1, lat2);
+ }
+
+ template <typename CalculationType>
+ static inline bool contains_pi_half(CalculationType const& a1,
+ CalculationType const& a2)
+ {
+ // azimuths a1 and a2 are assumed to be in radians
+ BOOST_GEOMETRY_ASSERT(! math::equals(a1, a2));
+
+ static CalculationType const pi_half = math::half_pi<CalculationType>();
+
+ return (a1 < a2)
+ ? (a1 < pi_half && pi_half < a2)
+ : (a1 > pi_half && pi_half > a2);
+ }
+
+ template <typename CoordinateType>
+ static inline bool crosses_antimeridian(CoordinateType const& lon1,
+ CoordinateType const& lon2)
+ {
+ return math::larger(math::abs(lon1 - lon2), math::pi<CoordinateType>());
+ }
+
+ template <typename CalculationType>
+ static inline CalculationType max_latitude(CalculationType const& azimuth,
+ CalculationType const& latitude)
+ {
+ // azimuth and latitude are assumed to be in radians
+ return acos( math::abs(cos(latitude) * sin(azimuth)) );
+ }
+
+ template <typename CalculationType>
+ static inline void compute_box_corners(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2,
+ CalculationType const& a1,
+ CalculationType const& a2)
+ {
+ // coordinates are assumed to be in radians
+ BOOST_GEOMETRY_ASSERT(! math::larger(lon1, lon2));
+
+ if (math::equals(a1, a2))
+ {
+ // the segment must lie on the equator; nothing to do
+ BOOST_GEOMETRY_ASSERT(math::equals(lat1, CalculationType(0)));
+ BOOST_GEOMETRY_ASSERT(math::equals(lat2, CalculationType(0)));
+ return;
+ }
+
+ if (math::larger(lat1, lat2))
+ {
+ std::swap(lat1, lat2);
+ }
+
+ if (contains_pi_half(a1, a2))
+ {
+ CalculationType mid_lat = lat1 + lat2;
+ if (mid_lat < 0)
+ {
+ // update using min latitude
+ CalculationType lat_min = -max_latitude(a1, lat1);
+
+ if (math::larger(lat1, lat_min))
+ {
+ lat1 = lat_min;
+ }
+ }
+ else if (mid_lat > 0)
+ {
+ // update using max latitude
+ CalculationType lat_max = max_latitude(a1, lat1);
+
+ if (math::smaller(lat2, lat_max))
+ {
+ lat2 = lat_max;
+ }
+ }
+ }
+ }
+
+ template <typename CalculationType>
+ static inline void apply(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2)
+ {
+ CalculationType const half_pi = math::half_pi<CalculationType>();
+
+ bool is_pole1 = math::equals(math::abs(lat1), half_pi);
+ bool is_pole2 = math::equals(math::abs(lat2), half_pi);
+
+ if (is_pole1 && is_pole2)
+ {
+ // both points are poles; nothing more to do:
+ // longitudes are already normalized to 0
+ BOOST_GEOMETRY_ASSERT(lon1 == CalculationType(0)
+ &&
+ lon2 == CalculationType(0));
+ }
+ else if (is_pole1 && !is_pole2)
+ {
+ // first point is a pole, second point is not:
+ // make the longitude of the first point the same as that
+ // of the second point
+ lon1 = lon2;
+ }
+ else if (!is_pole1 && is_pole2)
+ {
+ // second point is a pole, first point is not:
+ // make the longitude of the second point the same as that
+ // of the first point
+ lon2 = lon1;
+ }
+
+ if (math::equals(lon1, lon2))
+ {
+ // segment lies on a meridian
+ if (math::larger(lat1, lat2))
+ {
+ std::swap(lat1, lat2);
+ }
+ return;
+ }
+
+ BOOST_GEOMETRY_ASSERT(!is_pole1 && !is_pole2);
+
+ if (math::larger(lon1, lon2))
+ {
+ swap(lon1, lat1, lon2, lat2);
+ }
+
+ if (crosses_antimeridian(lon1, lon2))
+ {
+ lon1 += math::two_pi<CalculationType>();
+ swap(lon1, lat1, lon2, lat2);
+ }
+
+ CalculationType a1 = 0, a2 = 0;
+ azimuths(lon1, lat1, lon2, lat2, a1, a2);
+
+ compute_box_corners(lon1, lat1, lon2, lat2, a1, a2);
+ }
+
+public:
+ template <typename CalculationType, typename Box>
+ static inline void apply(CalculationType lon1,
+ CalculationType lat1,
+ CalculationType lon2,
+ CalculationType lat2,
+ Box& mbr)
+ {
+ typedef typename coordinate_type<Box>::type box_coordinate_type;
+
+ typename helper_geometry
+ <
+ Box, box_coordinate_type, radian
+ >::type radian_mbr;
+
+ apply(lon1, lat1, lon2, lat2);
+
+ assign_values(radian_mbr,
+ boost::numeric_cast<box_coordinate_type>(lon1),
+ boost::numeric_cast<box_coordinate_type>(lat1),
+ boost::numeric_cast<box_coordinate_type>(lon2),
+ boost::numeric_cast<box_coordinate_type>(lat2));
+
+ geometry::transform(radian_mbr, mbr);
+ }
+};
+
+
+struct envelope_segment_on_spheroid
+{
+ template <typename Point, typename Box>
+ static inline void apply(Point const& p1, Point const& p2, Box& mbr)
+ {
+ Point p1_normalized = detail::return_normalized<Point>(p1);
+ Point p2_normalized = detail::return_normalized<Point>(p2);
+
+ compute_mbr_of_segment::apply(geometry::get_as_radian<0>(p1_normalized),
+ geometry::get_as_radian<1>(p1_normalized),
+ geometry::get_as_radian<0>(p2_normalized),
+ geometry::get_as_radian<1>(p2_normalized),
+ mbr);
+ }
+};
+
+template <typename CSTag>
+struct envelope_one_segment
+{
+ template<typename Point, typename Box>
+ static inline void apply(Point const& p1, Point const& p2, Box& mbr)
+ {
+ envelope_one_point<CSTag>::apply(p1, mbr);
+ geometry::expand(mbr, p2);
+ }
+};
+
+template <>
+struct envelope_one_segment<spherical_equatorial_tag>
+ : envelope_segment_on_spheroid
+{};
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Segment>
+struct envelope<Segment, segment_tag>
+{
+ template <typename Box>
+ static inline void apply(Segment const& segment, Box& mbr)
+ {
+ typename point_type<Segment>::type p[2];
+ detail::assign_point_from_index<0>(segment, p[0]);
+ detail::assign_point_from_index<1>(segment, p[1]);
+ detail::envelope::envelope_one_segment
+ <
+ typename cs_tag<Segment>::type
+ >::apply(p[0], p[1], mbr);
+ }
+};
+
+
+} // namespace dispatch
+#endif
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/equals/collect_vectors.hpp b/3party/boost/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
index 5bcb5ffaa0..dc1cd74900 100644
--- a/3party/boost/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
@@ -17,7 +17,6 @@
#include <boost/numeric/conversion/cast.hpp>
-#include <boost/range.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
@@ -28,7 +27,7 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/util/math.hpp>
-
+#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -159,7 +158,7 @@ struct range_collect_vectors
if ( collected_count > 1 )
{
typedef typename boost::range_iterator<Collection>::type c_iterator;
- c_iterator first = collection.begin() + c_old_size;
+ c_iterator first = range::pos(collection, c_old_size);
if ( first->same_direction(collection.back()) )
{
diff --git a/3party/boost/boost/geometry/algorithms/detail/expand/box.hpp b/3party/boost/boost/geometry/algorithms/detail/expand/box.hpp
new file mode 100644
index 0000000000..94ea10d507
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/expand/box.hpp
@@ -0,0 +1,110 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_EXPAND_BOX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_BOX_HPP
+
+#include <algorithm>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+struct box_on_spheroid
+{
+ template <typename BoxOut, typename BoxIn>
+ static inline void apply(BoxOut& box_out, BoxIn const& box_in)
+ {
+ // normalize both boxes and convert box-in to be of type of box-out
+ BoxOut mbrs[2];
+ detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0]);
+ detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1]);
+
+ // compute the envelope of the two boxes
+ detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// Box + box -> new box containing two input boxes
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater,
+ typename CSTagOut, typename CSTag
+>
+struct expand
+ <
+ BoxOut, BoxIn, StrategyLess, StrategyGreater,
+ box_tag, box_tag, CSTagOut, CSTag
+ > : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
+{};
+
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, BoxIn, StrategyLess, StrategyGreater,
+ box_tag, box_tag, spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::expand::box_on_spheroid
+{};
+
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, BoxIn, StrategyLess, StrategyGreater,
+ box_tag, box_tag, geographic_tag, geographic_tag
+ > : detail::expand::box_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/expand/implementation.hpp b/3party/boost/boost/geometry/algorithms/detail/expand/implementation.hpp
new file mode 100644
index 0000000000..c48f2e681f
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/expand/implementation.hpp
@@ -0,0 +1,27 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_EXPAND_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_IMPLEMENTATION_HPP
+
+#include <boost/geometry/algorithms/detail/expand/point.hpp>
+#include <boost/geometry/algorithms/detail/expand/segment.hpp>
+#include <boost/geometry/algorithms/detail/expand/box.hpp>
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_IMPLEMENTATION_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/expand/indexed.hpp b/3party/boost/boost/geometry/algorithms/detail/expand/indexed.hpp
new file mode 100644
index 0000000000..10b85b1837
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/expand/indexed.hpp
@@ -0,0 +1,144 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_EXPAND_INDEXED_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Index,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct indexed_loop
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& box, Geometry const& source)
+ {
+ 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;
+
+ 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
+ <
+ StrategyLess, StrategyGreater,
+ Index, Dimension + 1, DimensionCount
+ >::apply(box, source);
+ }
+};
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Index, std::size_t DimensionCount
+>
+struct indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ Index, DimensionCount, DimensionCount
+ >
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box&, Geometry const&) {}
+};
+
+
+
+// Changes a box such that the other box is also contained by the box
+template
+<
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand_indexed
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& box, Geometry const& geometry)
+ {
+ indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ 0, 0, dimension<Geometry>::type::value
+ >::apply(box, geometry);
+
+ indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ 1, 0, dimension<Geometry>::type::value
+ >::apply(box, geometry);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/expand/interface.hpp b/3party/boost/boost/geometry/algorithms/detail/expand/interface.hpp
new file mode 100644
index 0000000000..3064f12363
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/expand/interface.hpp
@@ -0,0 +1,128 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_EXPAND_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct expand
+{
+ template <typename Box>
+ static inline void apply(Box& box, Geometry const& geometry)
+ {
+ concept::check<Box>();
+ concept::check<Geometry const>();
+ concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
+
+ dispatch::expand<Box, Geometry>::apply(box, geometry);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Box>
+ struct visitor: boost::static_visitor<void>
+ {
+ Box& m_box;
+
+ visitor(Box& box) : m_box(box) {}
+
+ template <typename Geometry>
+ void operator()(Geometry const& geometry) const
+ {
+ return expand<Geometry>::apply(m_box, geometry);
+ }
+ };
+
+ template <class Box>
+ static inline void
+ apply(Box& box,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ {
+ return boost::apply_visitor(visitor<Box>(box), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/***
+*!
+\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<Box, Geometry>::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)
+{
+ resolve_variant::expand<Geometry>::apply(box, geometry);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/expand/point.hpp b/3party/boost/boost/geometry/algorithms/detail/expand/point.hpp
new file mode 100644
index 0000000000..a510e37ed3
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/expand/point.hpp
@@ -0,0 +1,273 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_EXPAND_POINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
+
+#include <cstddef>
+#include <algorithm>
+
+#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/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/strategies/strategy_transform.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+struct point_on_spheroid
+{
+ template <typename Box, typename Point>
+ static inline void apply(Box& box, Point const& point)
+ {
+ typedef typename coordinate_type<Box>::type box_coordinate_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ box_coordinate_type,
+ typename coordinate_system<Box>::type::units
+ > constants;
+
+ // normalize input point and input box
+ Point p_normalized = detail::return_normalized<Point>(point);
+ detail::normalize(box, box);
+
+ // transform input point to be the same type as the box point
+ typename point_type<Box>::type box_point;
+ geometry::transform(p_normalized, box_point);
+
+ box_coordinate_type p_lon = geometry::get<0>(box_point);
+ box_coordinate_type p_lat = geometry::get<1>(box_point);
+
+ typename coordinate_type<Box>::type
+ b_lon_min = geometry::get<min_corner, 0>(box),
+ b_lat_min = geometry::get<min_corner, 1>(box),
+ b_lon_max = geometry::get<max_corner, 0>(box),
+ b_lat_max = geometry::get<max_corner, 1>(box);
+
+ if (math::equals(math::abs(p_lat), constants::max_latitude()))
+ {
+ // the point of expansion is the either the north or the
+ // south pole; the only important coordinate here is the
+ // pole's latitude, as the longitude can be anything;
+ // we, thus, take into account the point's latitude only and return
+ assign_values(box,
+ b_lon_min,
+ (std::min)(p_lat, b_lat_min),
+ b_lon_max,
+ (std::max)(p_lat, b_lat_max));
+ return;
+ }
+
+ if (math::equals(b_lat_min, b_lat_max)
+ && math::equals(math::abs(b_lat_min), constants::max_latitude()))
+ {
+ // the box degenerates to either the north or the south pole;
+ // the only important coordinate here is the pole's latitude,
+ // as the longitude can be anything;
+ // we thus take into account the box's latitude only and return
+ assign_values(box,
+ p_lon,
+ (std::min)(p_lat, b_lat_min),
+ p_lon,
+ (std::max)(p_lat, b_lat_max));
+ return;
+ }
+
+ // update latitudes
+ b_lat_min = (std::min)(b_lat_min, p_lat);
+ b_lat_max = (std::max)(b_lat_max, p_lat);
+
+ // update longitudes
+ if (math::smaller(p_lon, b_lon_min))
+ {
+ box_coordinate_type p_lon_shifted = p_lon + constants::period();
+
+ if (math::larger(p_lon_shifted, b_lon_max))
+ {
+ // here we could check using: ! math::larger(.., ..)
+ if (math::smaller(b_lon_min - p_lon, p_lon_shifted - b_lon_max))
+ {
+ b_lon_min = p_lon;
+ }
+ else
+ {
+ b_lon_max = p_lon_shifted;
+ }
+ }
+ }
+ else if (math::larger(p_lon, b_lon_max))
+ {
+ // in this case, and since p_lon is normalized in the range
+ // (-180, 180], we must have that b_lon_max <= 180
+ if (b_lon_min < 0
+ && math::larger(p_lon - b_lon_max,
+ constants::period() - p_lon + b_lon_min))
+ {
+ b_lon_min = p_lon;
+ b_lon_max += constants::period();
+ }
+ else
+ {
+ b_lon_max = p_lon;
+ }
+ }
+
+ assign_values(box, b_lon_min, b_lat_min, b_lon_max, b_lat_max);
+ }
+};
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_loop
+{
+ template <typename Box, typename Point>
+ static inline void apply(Box& box, Point const& source)
+ {
+ 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;
+
+ 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
+ <
+ StrategyLess, StrategyGreater,
+ Dimension + 1, DimensionCount
+ >::apply(box, source);
+ }
+};
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater, std::size_t DimensionCount
+>
+struct point_loop
+ <
+ StrategyLess, StrategyGreater, DimensionCount, DimensionCount
+ >
+{
+ template <typename Box, typename Point>
+ static inline void apply(Box&, Point const&) {}
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// Box + point -> new box containing also point
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater,
+ typename CSTagOut, typename CSTag
+>
+struct expand
+ <
+ BoxOut, Point, StrategyLess, StrategyGreater,
+ box_tag, point_tag, CSTagOut, CSTag
+ > : detail::expand::point_loop
+ <
+ StrategyLess, StrategyGreater,
+ 0, dimension<Point>::type::value
+ >
+{};
+
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, Point, StrategyLess, StrategyGreater,
+ box_tag, point_tag, spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::expand::point_on_spheroid
+{};
+
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, Point, StrategyLess, StrategyGreater,
+ box_tag, point_tag, geographic_tag, geographic_tag
+ > : detail::expand::point_on_spheroid
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/expand/segment.hpp b/3party/boost/boost/geometry/algorithms/detail/expand/segment.hpp
new file mode 100644
index 0000000000..917ab20021
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/expand/segment.hpp
@@ -0,0 +1,91 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_EXPAND_SEGMENT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
+#include <boost/geometry/algorithms/detail/expand/box.hpp>
+#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+struct segment_on_spheroid
+{
+ template <typename Box, typename Segment>
+ static inline void apply(Box& box, Segment const& segment)
+ {
+ Box segment_envelope;
+ dispatch::envelope<Segment>::apply(segment, segment_envelope);
+ box_on_spheroid::apply(box, segment_envelope);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Box, typename Segment,
+ typename StrategyLess, typename StrategyGreater,
+ typename CSTagOut, typename CSTag
+>
+struct expand
+ <
+ Box, Segment, StrategyLess, StrategyGreater,
+ box_tag, segment_tag, CSTagOut, CSTag
+ > : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
+{};
+
+template
+<
+ typename Box, typename Segment,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ Box, Segment, StrategyLess, StrategyGreater,
+ box_tag, segment_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::expand::segment_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/extreme_points.hpp b/3party/boost/boost/geometry/algorithms/detail/extreme_points.hpp
index c6a47bb8f4..61839d296a 100644
--- a/3party/boost/boost/geometry/algorithms/detail/extreme_points.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/extreme_points.hpp
@@ -89,7 +89,8 @@ inline void move_along_vector(PointType& point, PointType const& extreme, Coordi
CoordinateType const base_diff = base_value - geometry::get<Dimension>(extreme);
- multiply_value(vector, base_diff / diff);
+ multiply_value(vector, base_diff);
+ divide_value(vector, diff);
// The real move:
point = extreme;
@@ -236,8 +237,9 @@ struct extreme_points_on_ring
coordinate_type const other_coordinate = geometry::get<1 - Dimension>(*right);
if (coordinate > min_value && other_coordinate > other_min && other_coordinate < other_max)
{
- int const first_side = side_strategy::apply(*right, extremes.front(), *(extremes.begin() + 1));
- int const last_side = side_strategy::apply(*right, *(extremes.rbegin() + 1), extremes.back());
+ int const factor = geometry::point_order<Ring>::value == geometry::clockwise ? 1 : -1;
+ int const first_side = side_strategy::apply(*right, extremes.front(), *(extremes.begin() + 1)) * factor;
+ int const last_side = side_strategy::apply(*right, *(extremes.rbegin() + 1), extremes.back()) * factor;
// If not lying left from any of the extemes side
if (first_side != 1 && last_side != 1)
@@ -280,7 +282,8 @@ struct extreme_points_on_ring
template <typename Iterator>
static inline bool right_turn(Ring const& ring, Iterator it)
{
- int const index = std::distance(boost::begin(ring), it);
+ typename std::iterator_traits<Iterator>::difference_type const index
+ = std::distance(boost::begin(ring), it);
geometry::ever_circling_range_iterator<Ring const> left(ring);
geometry::ever_circling_range_iterator<Ring const> right(ring);
left += index;
@@ -291,8 +294,9 @@ struct extreme_points_on_ring
return false;
}
- int const first_side = side_strategy::apply(*(right - 1), *right, *left);
- int const last_side = side_strategy::apply(*left, *(left + 1), *right);
+ int const factor = geometry::point_order<Ring>::value == geometry::clockwise ? 1 : -1;
+ int const first_side = side_strategy::apply(*(right - 1), *right, *left) * factor;
+ int const last_side = side_strategy::apply(*left, *(left + 1), *right) * factor;
//std::cout << "Candidate at " << geometry::wkt(*it) << " first=" << first_side << " last=" << last_side << std::endl;
@@ -328,7 +332,8 @@ struct extreme_points_on_ring
return false;
}
- int const index = std::distance(boost::begin(ring), max_it);
+ typename std::iterator_traits<range_iterator>::difference_type const
+ index = std::distance(boost::begin(ring), max_it);
//std::cout << "Extreme point lies at " << index << " having " << geometry::wkt(*max_it) << std::endl;
geometry::ever_circling_range_iterator<Ring const> left(ring);
diff --git a/3party/boost/boost/geometry/algorithms/detail/flattening.hpp b/3party/boost/boost/geometry/algorithms/detail/flattening.hpp
new file mode 100644
index 0000000000..8ed5fd9a89
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/flattening.hpp
@@ -0,0 +1,69 @@
+// Boost.Geometry
+
+// Copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_FLATTENING_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_FLATTENING_HPP
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace detail_dispatch
+{
+
+template <typename ResultType, typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct flattening
+ : not_implemented<Tag>
+{};
+
+template <typename ResultType, typename Geometry>
+struct flattening<ResultType, Geometry, srs_sphere_tag>
+{
+ static inline ResultType apply(Geometry const& /*geometry*/)
+ {
+ return ResultType(0);
+ }
+};
+
+template <typename ResultType, typename Geometry>
+struct flattening<ResultType, Geometry, srs_spheroid_tag>
+{
+ static inline ResultType apply(Geometry const& geometry)
+ {
+ return ResultType(get_radius<0>(geometry) - get_radius<2>(geometry))
+ / ResultType(get_radius<0>(geometry));
+ }
+};
+
+} // namespace detail_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename ResultType, typename Geometry>
+ResultType flattening(Geometry const& geometry)
+{
+ return detail_dispatch::flattening<ResultType, Geometry>::apply(geometry);
+}
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_FLATTENING_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/get_left_turns.hpp b/3party/boost/boost/geometry/algorithms/detail/get_left_turns.hpp
index deb2aaf59d..3361b139c3 100644
--- a/3party/boost/boost/geometry/algorithms/detail/get_left_turns.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/get_left_turns.hpp
@@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
@@ -34,39 +36,7 @@ inline std::pair<T, T> ordered_pair(T const& first, T const& second)
namespace left_turns
{
-template <typename Point>
-struct turn_angle_info
-{
- segment_identifier seg_id;
- int turn_index;
- Point points[2];
-
- turn_angle_info(segment_identifier const& id, Point const& from, Point const& to)
- : seg_id(id)
- , turn_index(-1)
- {
- points[0] = from;
- points[1] = to;
- }
-};
-
-template <typename Point>
-struct angle_info
-{
- segment_identifier seg_id;
- Point point;
- bool incoming;
- bool blocked;
-
- inline angle_info(segment_identifier const& id, bool inc, Point const& p)
- : seg_id(id)
- , point(p)
- , incoming(inc)
- , blocked(false)
- {
- }
-};
template <typename Vector>
inline int get_quadrant(Vector const& vector)
@@ -125,12 +95,13 @@ struct angle_less
{
return side == 1;
}
- // Collinear, check if one is incoming
+ // Collinear, check if one is incoming, incoming angles come first
if (p.incoming != q.incoming)
{
return int(p.incoming) < int(q.incoming);
}
// Same quadrant/side/direction, return longest first
+ // TODO: maybe not necessary, decide this
int const length_p = squared_length(pv);
int const length_q = squared_length(qv);
if (length_p != length_q)
@@ -181,87 +152,142 @@ private:
Point m_origin;
};
-struct left_turn
+template <typename AngleCollection, typename Turns>
+inline void get_left_turns(AngleCollection const& sorted_angles,
+ Turns& turns)
{
- segment_identifier from;
- segment_identifier to;
-};
+ std::set<int> good_incoming;
+ std::set<int> good_outgoing;
+ for (typename boost::range_iterator<AngleCollection const>::type it =
+ sorted_angles.begin(); it != sorted_angles.end(); ++it)
+ {
+ if (!it->blocked)
+ {
+ if (it->incoming)
+ {
+ good_incoming.insert(it->turn_index);
+ }
+ else
+ {
+ good_outgoing.insert(it->turn_index);
+ }
+ }
+ }
-template <typename Point, typename AngleCollection, typename OutputCollection>
-inline void get_left_turns(AngleCollection const& sorted_angles, Point const& origin,
- OutputCollection& output_collection)
+ if (good_incoming.empty() || good_outgoing.empty())
+ {
+ return;
+ }
+
+ for (typename boost::range_iterator<AngleCollection const>::type it =
+ sorted_angles.begin(); it != sorted_angles.end(); ++it)
+ {
+ if (good_incoming.count(it->turn_index) == 0
+ || good_outgoing.count(it->turn_index) == 0)
+ {
+ turns[it->turn_index].remove_on_multi = true;
+ }
+ }
+}
+
+
+//! Returns the number of clusters
+template <typename Point, typename AngleCollection>
+inline std::size_t assign_cluster_indices(AngleCollection& sorted, Point const& origin)
{
+ // Assign same cluster_index for all turns in same direction
+ BOOST_GEOMETRY_ASSERT(boost::size(sorted) >= 4u);
+
angle_equal_to<Point> comparator(origin);
- typedef geometry::closing_iterator<AngleCollection const> closing_iterator;
- closing_iterator it(sorted_angles);
- closing_iterator end(sorted_angles, true);
+ typename boost::range_iterator<AngleCollection>::type it = sorted.begin();
- closing_iterator previous = it++;
- for( ; it != end; previous = it++)
+ std::size_t cluster_index = 0;
+ it->cluster_index = cluster_index;
+ typename boost::range_iterator<AngleCollection>::type previous = it++;
+ for (; it != sorted.end(); ++it)
{
- if (! it->blocked)
+ if (!comparator(*previous, *it))
{
- bool equal = comparator(*previous, *it);
- bool include = ! equal
- && previous->incoming
- && !it->incoming;
- if (include)
- {
- left_turn turn;
- turn.from = previous->seg_id;
- turn.to = it->seg_id;
- output_collection.push_back(turn);
- }
+ cluster_index++;
+ previous = it;
}
+ it->cluster_index = cluster_index;
}
+ return cluster_index + 1;
}
-template <typename AngleTurnCollection, typename AngleCollection>
-inline void block_turns_on_right_sides(AngleTurnCollection const& turns,
- AngleCollection& sorted)
+template <typename AngleCollection>
+inline void block_turns(AngleCollection& sorted, std::size_t cluster_size)
{
- // Create a small (seg_id -> index) map for fast finding turns
- std::map<segment_identifier, int> incoming;
- std::map<segment_identifier, int> outgoing;
- int index = 0;
- for (typename boost::range_iterator<AngleCollection>::type it =
- sorted.begin(); it != sorted.end(); ++it, ++index)
+ BOOST_GEOMETRY_ASSERT(boost::size(sorted) >= 4u && cluster_size > 0);
+
+ std::vector<std::pair<bool, bool> > directions;
+ for (std::size_t i = 0; i < cluster_size; i++)
+ {
+ directions.push_back(std::make_pair(false, false));
+ }
+
+ for (typename boost::range_iterator<AngleCollection const>::type it = sorted.begin();
+ it != sorted.end(); ++it)
{
if (it->incoming)
{
- incoming[it->seg_id] = index;
+ directions[it->cluster_index].first = true;
}
else
{
- outgoing[it->seg_id] = index;
+ directions[it->cluster_index].second = true;
}
}
- // Walk through turns and block every outgoing angle on the right side
- for (typename boost::range_iterator<AngleTurnCollection const>::type it =
- turns.begin(); it != turns.end(); ++it)
+ for (typename boost::range_iterator<AngleCollection>::type it = sorted.begin();
+ it != sorted.end(); ++it)
{
- int incoming_index = incoming[it->seg_id];
- int outgoing_index = outgoing[it->seg_id];
- int index = incoming_index;
- while(index != outgoing_index)
+ int cluster_index = it->cluster_index;
+ int previous_index = cluster_index - 1;
+ if (previous_index < 0)
{
- if (!sorted[index].incoming)
- {
- sorted[index].blocked = true;
- }
+ previous_index = cluster_size - 1;
+ }
+ int next_index = cluster_index + 1;
+ if (next_index >= static_cast<int>(cluster_size))
+ {
+ next_index = 0;
+ }
- // Go back (circular)
- index--;
- if (index == -1)
- {
- index = boost::size(sorted) - 1;
- }
+ if (directions[cluster_index].first
+ && directions[cluster_index].second)
+ {
+ it->blocked = true;
+ }
+ else if (!directions[cluster_index].first
+ && directions[cluster_index].second
+ && directions[previous_index].second)
+ {
+ // Only outgoing, previous was also outgoing: block this one
+ it->blocked = true;
+ }
+ else if (directions[cluster_index].first
+ && !directions[cluster_index].second
+ && !directions[previous_index].first
+ && directions[previous_index].second)
+ {
+ // Only incoming, previous was only outgoing: block this one
+ it->blocked = true;
+ }
+ else if (directions[cluster_index].first
+ && !directions[cluster_index].second
+ && directions[next_index].first
+ && !directions[next_index].second)
+ {
+ // Only incoming, next also incoming, block this one
+ it->blocked = true;
}
}
}
+#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
template <typename AngleCollection, typename Point>
inline bool has_rounding_issues(AngleCollection const& angles, Point const& origin)
{
@@ -278,6 +304,7 @@ inline bool has_rounding_issues(AngleCollection const& angles, Point const& orig
}
return false;
}
+#endif
} // namespace left_turns
diff --git a/3party/boost/boost/geometry/algorithms/detail/intersection/box_box.hpp b/3party/boost/boost/geometry/algorithms/detail/intersection/box_box.hpp
new file mode 100644
index 0000000000..30c31ff1e5
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/intersection/box_box.hpp
@@ -0,0 +1,54 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INTERSECTION_BOX_BOX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_BOX_BOX_HPP
+
+
+#include <boost/geometry/algorithms/detail/intersection/interface.hpp>
+#include <boost/geometry/algorithms/detail/overlay/intersection_box_box.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Box1, typename Box2, bool Reverse
+>
+struct intersection
+ <
+ Box1, Box2,
+ box_tag, box_tag,
+ Reverse
+ > : public detail::intersection::intersection_box_box
+ <
+ 0, geometry::dimension<Box1>::value
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_BOX_BOX_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/intersection/implementation.hpp b/3party/boost/boost/geometry/algorithms/detail/intersection/implementation.hpp
new file mode 100644
index 0000000000..d8fb2ec38c
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/intersection/implementation.hpp
@@ -0,0 +1,22 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INTERSECTION_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_IMPLEMENTATION_HPP
+
+
+#include <boost/geometry/algorithms/detail/intersection/box_box.hpp>
+#include <boost/geometry/algorithms/detail/intersection/multi.hpp>
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_IMPLEMENTATION_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/intersection/interface.hpp b/3party/boost/boost/geometry/algorithms/detail/intersection/interface.hpp
new file mode 100644
index 0000000000..d57535e61f
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/intersection/interface.hpp
@@ -0,0 +1,309 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INTERSECTION_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP
+
+
+// TODO: those headers probably may be removed
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
+#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// By default, all is forwarded to the intersection_insert-dispatcher
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename Tag1 = typename geometry::tag<Geometry1>::type,
+ typename Tag2 = typename geometry::tag<Geometry2>::type,
+ bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
+>
+struct intersection
+{
+ template <typename RobustPolicy, typename GeometryOut, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ GeometryOut& geometry_out,
+ Strategy const& strategy)
+ {
+ typedef typename boost::range_value<GeometryOut>::type OneOut;
+
+ intersection_insert
+ <
+ Geometry1, Geometry2, OneOut,
+ overlay_intersection
+ >::apply(geometry1, geometry2, robust_policy, std::back_inserter(geometry_out), strategy);
+
+ return true;
+ }
+
+};
+
+
+// If reversal is needed, perform it
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename Tag1, typename Tag2
+>
+struct intersection
+<
+ Geometry1, Geometry2,
+ Tag1, Tag2,
+ true
+>
+ : intersection<Geometry2, Geometry1, Tag2, Tag1, false>
+{
+ template <typename RobustPolicy, typename GeometryOut, typename Strategy>
+ static inline bool apply(
+ Geometry1 const& g1,
+ Geometry2 const& g2,
+ RobustPolicy const& robust_policy,
+ GeometryOut& out,
+ Strategy const& strategy)
+ {
+ return intersection<
+ Geometry2, Geometry1,
+ Tag2, Tag1,
+ false
+ >::apply(g2, g1, robust_policy, out, strategy);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry1, typename Geometry2>
+struct intersection
+{
+ template <typename GeometryOut>
+ static inline bool
+ apply(
+ const Geometry1& geometry1,
+ const Geometry2& geometry2,
+ GeometryOut& geometry_out)
+ {
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ typedef typename geometry::rescale_overlay_policy_type
+ <
+ Geometry1,
+ Geometry2
+ >::type rescale_policy_type;
+
+ rescale_policy_type robust_policy
+ = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
+
+ typedef strategy_intersection
+ <
+ typename cs_tag<Geometry1>::type,
+ Geometry1,
+ Geometry2,
+ typename geometry::point_type<Geometry1>::type,
+ rescale_policy_type
+ > strategy;
+
+ return dispatch::intersection
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, robust_policy, geometry_out, strategy());
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename GeometryOut>
+ struct visitor: static_visitor<bool>
+ {
+ Geometry2 const& m_geometry2;
+ GeometryOut& m_geometry_out;
+
+ visitor(Geometry2 const& geometry2,
+ GeometryOut& geometry_out)
+ : m_geometry2(geometry2),
+ m_geometry_out(geometry_out)
+ {}
+
+ template <typename Geometry1>
+ result_type operator()(Geometry1 const& geometry1) const
+ {
+ return intersection
+ <
+ Geometry1,
+ Geometry2
+ >::template apply
+ <
+ GeometryOut
+ >
+ (geometry1, m_geometry2, m_geometry_out);
+ }
+ };
+
+ template <typename GeometryOut>
+ static inline bool
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& geometry_out)
+ {
+ return apply_visitor(visitor<GeometryOut>(geometry2, geometry_out), geometry1);
+ }
+};
+
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename GeometryOut>
+ struct visitor: static_visitor<bool>
+ {
+ Geometry1 const& m_geometry1;
+ GeometryOut& m_geometry_out;
+
+ visitor(Geometry1 const& geometry1,
+ GeometryOut& geometry_out)
+ : m_geometry1(geometry1),
+ m_geometry_out(geometry_out)
+ {}
+
+ template <typename Geometry2>
+ result_type operator()(Geometry2 const& geometry2) const
+ {
+ return intersection
+ <
+ Geometry1,
+ Geometry2
+ >::template apply
+ <
+ GeometryOut
+ >
+ (m_geometry1, geometry2, m_geometry_out);
+ }
+ };
+
+ template <typename GeometryOut>
+ static inline bool
+ apply(
+ Geometry1 const& geometry1,
+ const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
+ GeometryOut& geometry_out)
+ {
+ return apply_visitor(visitor<GeometryOut>(geometry1, geometry_out), geometry2);
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
+struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
+{
+ template <typename GeometryOut>
+ struct visitor: static_visitor<bool>
+ {
+ GeometryOut& m_geometry_out;
+
+ visitor(GeometryOut& geometry_out)
+ : m_geometry_out(geometry_out)
+ {}
+
+ template <typename Geometry1, typename Geometry2>
+ result_type operator()(
+ Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ return intersection
+ <
+ Geometry1,
+ Geometry2
+ >::template apply
+ <
+ GeometryOut
+ >
+ (geometry1, geometry2, m_geometry_out);
+ }
+ };
+
+ template <typename GeometryOut>
+ static inline bool
+ apply(
+ const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
+ const variant<BOOST_VARIANT_ENUM_PARAMS(T2)>& geometry2,
+ GeometryOut& geometry_out)
+ {
+ return apply_visitor(visitor<GeometryOut>(geometry_out), geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/*!
+\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)
+{
+ return resolve_variant::intersection
+ <
+ Geometry1,
+ Geometry2
+ >::template apply
+ <
+ GeometryOut
+ >
+ (geometry1, geometry2, geometry_out);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/intersection/multi.hpp b/3party/boost/boost/geometry/algorithms/detail/intersection/multi.hpp
new file mode 100644
index 0000000000..88b49b0167
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/intersection/multi.hpp
@@ -0,0 +1,421 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INTERSECTION_MULTI_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/geometry_id.hpp>
+#include <boost/geometry/core/is_areal.hpp>
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+// TODO: those headers probably may be removed
+#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
+#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
+#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
+#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
+#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
+
+#include <boost/geometry/algorithms/detail/intersection/interface.hpp>
+
+#include <boost/geometry/algorithms/covered_by.hpp>
+#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection
+{
+
+
+template <typename PointOut>
+struct intersection_multi_linestring_multi_linestring_point
+{
+ template
+ <
+ typename MultiLinestring1, typename MultiLinestring2,
+ typename RobustPolicy,
+ typename OutputIterator, typename Strategy
+ >
+ static inline OutputIterator apply(MultiLinestring1 const& ml1,
+ MultiLinestring2 const& ml2,
+ RobustPolicy const& robust_policy,
+ 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<PointOut>
+ ::apply(*it1, *it2, robust_policy, out, strategy);
+ }
+ }
+
+ return out;
+ }
+};
+
+
+template <typename PointOut>
+struct intersection_linestring_multi_linestring_point
+{
+ template
+ <
+ typename Linestring, typename MultiLinestring,
+ typename RobustPolicy,
+ typename OutputIterator, typename Strategy
+ >
+ static inline OutputIterator apply(Linestring const& linestring,
+ MultiLinestring const& ml,
+ RobustPolicy const& robust_policy,
+ 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<PointOut>
+ ::apply(linestring, *it, robust_policy, 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
+<
+ bool ReverseAreal,
+ typename LineStringOut,
+ overlay_type OverlayType
+>
+struct intersection_of_multi_linestring_with_areal
+{
+ template
+ <
+ typename MultiLinestring, typename Areal,
+ typename RobustPolicy,
+ typename OutputIterator, typename Strategy
+ >
+ static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
+ RobustPolicy const& robust_policy,
+ 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
+ <
+ ReverseAreal, LineStringOut, OverlayType
+ >::apply(*it, areal, robust_policy, out, strategy);
+ }
+
+ return out;
+
+ }
+};
+
+// This one calls the one above with reversed arguments
+template
+<
+ bool ReverseAreal,
+ typename LineStringOut,
+ overlay_type OverlayType
+>
+struct intersection_of_areal_with_multi_linestring
+{
+ template
+ <
+ typename Areal, typename MultiLinestring,
+ typename RobustPolicy,
+ typename OutputIterator, typename Strategy
+ >
+ static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ return intersection_of_multi_linestring_with_areal
+ <
+ ReverseAreal, LineStringOut, OverlayType
+ >::apply(ml, areal, robust_policy, out, strategy);
+ }
+};
+
+
+
+template <typename LinestringOut>
+struct clip_multi_linestring
+{
+ template
+ <
+ typename MultiLinestring, typename Box,
+ typename RobustPolicy,
+ typename OutputIterator, typename Strategy
+ >
+ static inline OutputIterator apply(MultiLinestring const& multi_linestring,
+ Box const& box,
+ RobustPolicy const& robust_policy,
+ 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, robust_policy, out, lb_strategy);
+ }
+ return out;
+ }
+};
+
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// Linear
+template
+<
+ typename MultiLinestring1, typename MultiLinestring2,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ bool Reverse1, bool Reverse2, bool ReverseOut
+>
+struct intersection_insert
+ <
+ MultiLinestring1, MultiLinestring2,
+ GeometryOut,
+ OverlayType,
+ Reverse1, Reverse2, ReverseOut,
+ multi_linestring_tag, multi_linestring_tag, point_tag,
+ false, false, false
+ > : detail::intersection::intersection_multi_linestring_multi_linestring_point
+ <
+ GeometryOut
+ >
+{};
+
+
+template
+<
+ typename Linestring, typename MultiLinestring,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ bool Reverse1, bool Reverse2, bool ReverseOut
+>
+struct intersection_insert
+ <
+ Linestring, MultiLinestring,
+ GeometryOut,
+ OverlayType,
+ Reverse1, Reverse2, ReverseOut,
+ linestring_tag, multi_linestring_tag, point_tag,
+ false, false, false
+ > : detail::intersection::intersection_linestring_multi_linestring_point
+ <
+ GeometryOut
+ >
+{};
+
+
+template
+<
+ typename MultiLinestring, typename Box,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ bool Reverse1, bool Reverse2, bool ReverseOut
+>
+struct intersection_insert
+ <
+ MultiLinestring, Box,
+ GeometryOut,
+ OverlayType,
+ Reverse1, Reverse2, ReverseOut,
+ multi_linestring_tag, box_tag, linestring_tag,
+ false, true, false
+ > : detail::intersection::clip_multi_linestring
+ <
+ GeometryOut
+ >
+{};
+
+
+template
+<
+ typename Linestring, typename MultiPolygon,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut
+>
+struct intersection_insert
+ <
+ Linestring, MultiPolygon,
+ GeometryOut,
+ OverlayType,
+ ReverseLinestring, ReverseMultiPolygon, ReverseOut,
+ linestring_tag, multi_polygon_tag, linestring_tag,
+ false, true, false
+ > : detail::intersection::intersection_of_linestring_with_areal
+ <
+ ReverseMultiPolygon,
+ GeometryOut,
+ OverlayType
+ >
+{};
+
+
+// Derives from areal/mls because runtime arguments are in that order.
+// areal/mls reverses it itself to mls/areal
+template
+<
+ typename Polygon, typename MultiLinestring,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut
+>
+struct intersection_insert
+ <
+ Polygon, MultiLinestring,
+ GeometryOut,
+ OverlayType,
+ ReversePolygon, ReverseMultiLinestring, ReverseOut,
+ polygon_tag, multi_linestring_tag, linestring_tag,
+ true, false, false
+ > : detail::intersection::intersection_of_areal_with_multi_linestring
+ <
+ ReversePolygon,
+ GeometryOut,
+ OverlayType
+ >
+{};
+
+
+template
+<
+ typename MultiLinestring, typename Ring,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
+>
+struct intersection_insert
+ <
+ MultiLinestring, Ring,
+ GeometryOut,
+ OverlayType,
+ ReverseMultiLinestring, ReverseRing, ReverseOut,
+ multi_linestring_tag, ring_tag, linestring_tag,
+ false, true, false
+ > : detail::intersection::intersection_of_multi_linestring_with_areal
+ <
+ ReverseRing,
+ GeometryOut,
+ OverlayType
+ >
+{};
+
+template
+<
+ typename MultiLinestring, typename Polygon,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
+>
+struct intersection_insert
+ <
+ MultiLinestring, Polygon,
+ GeometryOut,
+ OverlayType,
+ ReverseMultiLinestring, ReverseRing, ReverseOut,
+ multi_linestring_tag, polygon_tag, linestring_tag,
+ false, true, false
+ > : detail::intersection::intersection_of_multi_linestring_with_areal
+ <
+ ReverseRing,
+ GeometryOut,
+ OverlayType
+ >
+{};
+
+
+
+template
+<
+ typename MultiLinestring, typename MultiPolygon,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut
+>
+struct intersection_insert
+ <
+ MultiLinestring, MultiPolygon,
+ GeometryOut,
+ OverlayType,
+ ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut,
+ multi_linestring_tag, multi_polygon_tag, linestring_tag,
+ false, true, false
+ > : detail::intersection::intersection_of_multi_linestring_with_areal
+ <
+ ReverseMultiPolygon,
+ GeometryOut,
+ OverlayType
+ >
+{};
+
+
+} // namespace dispatch
+#endif
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
+
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_simple/areal.hpp b/3party/boost/boost/geometry/algorithms/detail/is_simple/areal.hpp
index 9a1a16507a..623632c44e 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_simple/areal.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_simple/areal.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -19,6 +19,7 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/detail/is_simple/failure_policy.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp>
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
@@ -38,11 +39,12 @@ struct is_simple_ring
{
static inline bool apply(Ring const& ring)
{
+ simplicity_failure_policy policy;
return
!detail::is_valid::has_duplicates
<
Ring, geometry::closure<Ring>::value
- >::apply(ring);
+ >::apply(ring, policy);
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_simple/debug_print_boundary_points.hpp b/3party/boost/boost/geometry/algorithms/detail/is_simple/debug_print_boundary_points.hpp
index 75c37c68f8..196d89b925 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_simple/debug_print_boundary_points.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_simple/debug_print_boundary_points.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -18,6 +18,8 @@
#include <boost/range.hpp>
#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/range.hpp>
@@ -26,7 +28,8 @@
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/algorithms/equals.hpp>
-#endif
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#endif // BOOST_GEOMETRY_TEST_DEBUG
namespace boost { namespace geometry
@@ -37,39 +40,67 @@ namespace detail { namespace is_simple
#ifdef BOOST_GEOMETRY_TEST_DEBUG
-template <typename MultiLinestring>
-inline void debug_print_boundary_points(MultiLinestring const& multilinestring)
+template <typename Linear, typename Tag = typename tag<Linear>::type>
+struct debug_boundary_points_printer
+ : not_implemented<Linear>
+{};
+
+template <typename Linestring>
+struct debug_boundary_points_printer<Linestring, linestring_tag>
{
- typedef typename point_type<MultiLinestring>::type point_type;
- typedef std::vector<point_type> point_vector;
+ static inline void apply(Linestring const& linestring)
+ {
+ std::cout << "boundary points: ";
+ std::cout << " " << geometry::dsv(range::front(linestring));
+ std::cout << " " << geometry::dsv(range::back(linestring));
+ std::cout << std::endl << std::endl;
+ }
+};
- point_vector boundary_points;
- for (typename boost::range_iterator<MultiLinestring const>::type it
- = boost::begin(multilinestring);
- it != boost::end(multilinestring); ++it)
+template <typename MultiLinestring>
+struct debug_boundary_points_printer<MultiLinestring, multi_linestring_tag>
+{
+ static inline void apply(MultiLinestring const& multilinestring)
{
- if ( boost::size(*it) > 1
- && !geometry::equals(range::front(*it), range::back(*it)) )
+ typedef typename point_type<MultiLinestring>::type point_type;
+ typedef std::vector<point_type> point_vector;
+
+ point_vector boundary_points;
+ for (typename boost::range_iterator<MultiLinestring const>::type it
+ = boost::begin(multilinestring);
+ it != boost::end(multilinestring); ++it)
{
- boundary_points.push_back( range::front(*it) );
- boundary_points.push_back( range::back(*it) );
+ if ( boost::size(*it) > 1
+ && !geometry::equals(range::front(*it), range::back(*it)) )
+ {
+ boundary_points.push_back( range::front(*it) );
+ boundary_points.push_back( range::back(*it) );
+ }
}
- }
- std::sort(boundary_points.begin(), boundary_points.end(),
- geometry::less<point_type>());
+ std::sort(boundary_points.begin(), boundary_points.end(),
+ geometry::less<point_type>());
- std::cout << "boundary points: ";
- for (typename point_vector::const_iterator pit = boundary_points.begin();
- pit != boundary_points.end(); ++pit)
- {
- std::cout << " " << geometry::dsv(*pit);
+ std::cout << "boundary points: ";
+ for (typename point_vector::const_iterator
+ pit = boundary_points.begin();
+ pit != boundary_points.end(); ++pit)
+ {
+ std::cout << " " << geometry::dsv(*pit);
+ }
+ std::cout << std::endl << std::endl;
}
- std::cout << std::endl << std::endl;
+};
+
+
+template <typename Linear>
+inline void debug_print_boundary_points(Linear const& linear)
+{
+ debug_boundary_points_printer<Linear>::apply(linear);
}
#else
-template <typename MultiLinestring>
-inline void debug_print_boundary_points(MultiLinestring const&)
+template <typename Linear>
+inline void debug_print_boundary_points(Linear const&)
{
}
#endif // BOOST_GEOMETRY_TEST_DEBUG
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_simple/failure_policy.hpp b/3party/boost/boost/geometry/algorithms/detail/is_simple/failure_policy.hpp
new file mode 100644
index 0000000000..6504edd1d5
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/is_simple/failure_policy.hpp
@@ -0,0 +1,53 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_FAILURE_POLICY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_FAILURE_POLICY_HPP
+
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace is_simple
+{
+
+
+struct simplicity_failure_policy
+{
+ template <validity_failure_type Failure>
+ static inline bool apply()
+ {
+ return Failure == no_failure;
+ }
+
+ template <validity_failure_type Failure, typename Data>
+ static inline bool apply(Data const&)
+ {
+ return apply<Failure>();
+ }
+
+ template <validity_failure_type Failure, typename Data1, typename Data2>
+ static inline bool apply(Data1 const&, Data2 const&)
+ {
+ return apply<Failure>();
+ }
+};
+
+
+}} // namespace detail::is_simple
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_FAILURE_POLICY_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_simple/interface.hpp b/3party/boost/boost/geometry/algorithms/detail/is_simple/interface.hpp
index 4239664ed1..fd84826970 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_simple/interface.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_simple/interface.hpp
@@ -10,8 +10,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_INTERFACE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_INTERFACE_HPP
-#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_simple/linear.hpp b/3party/boost/boost/geometry/algorithms/detail/is_simple/linear.hpp
index 18c33bfc3a..50866d67ab 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_simple/linear.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_simple/linear.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -13,12 +13,13 @@
#include <algorithm>
#include <deque>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/range.hpp>
@@ -29,8 +30,10 @@
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
@@ -40,6 +43,7 @@
#include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp>
#include <boost/geometry/algorithms/detail/is_simple/debug_print_boundary_points.hpp>
+#include <boost/geometry/algorithms/detail/is_simple/failure_policy.hpp>
#include <boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp>
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
@@ -54,108 +58,211 @@ namespace detail { namespace is_simple
{
-template <typename Linestring, bool CheckSelfIntersections = true>
-struct is_simple_linestring
+template <typename Turn>
+inline bool check_segment_indices(Turn const& turn,
+ signed_index_type last_index)
{
- static inline bool apply(Linestring const& linestring)
+ return
+ (turn.operations[0].seg_id.segment_index == 0
+ && turn.operations[1].seg_id.segment_index == last_index)
+ ||
+ (turn.operations[0].seg_id.segment_index == 0
+ && turn.operations[1].seg_id.segment_index == last_index);
+}
+
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+class is_acceptable_turn
+ : not_implemented<Geometry>
+{};
+
+template <typename Linestring>
+class is_acceptable_turn<Linestring, linestring_tag>
+{
+public:
+ is_acceptable_turn(Linestring const& linestring)
+ : m_linestring(linestring)
+ , m_is_closed(geometry::equals(range::front(linestring),
+ range::back(linestring)))
+ {}
+
+ template <typename Turn>
+ inline bool apply(Turn const& turn) const
{
- return !detail::is_valid::has_duplicates
- <
- Linestring, closed
- >::apply(linestring)
- && !detail::is_valid::has_spikes
- <
- Linestring, closed
- >::apply(linestring)
- && !(CheckSelfIntersections && geometry::intersects(linestring));
+ BOOST_GEOMETRY_ASSERT(boost::size(m_linestring) > 1);
+ return m_is_closed
+ && turn.method == overlay::method_none
+ && check_segment_indices(turn, boost::size(m_linestring) - 2)
+ && turn.operations[0].fraction.is_zero();
}
-};
-
+private:
+ Linestring const& m_linestring;
+ bool const m_is_closed;
+};
template <typename MultiLinestring>
-class is_simple_multilinestring
+class is_acceptable_turn<MultiLinestring, multi_linestring_tag>
{
private:
- class is_acceptable_turn
+ typedef typename boost::range_value<MultiLinestring>::type linestring_type;
+ typedef is_acceptable_turn<linestring_type> base_type;
+
+ template <typename Point, typename Linestring>
+ static inline bool is_boundary_point_of(Point const& point,
+ Linestring const& linestring)
{
- private:
- template <typename Point, typename Linestring>
- static inline bool is_boundary_point_of(Point const& point,
- Linestring const& linestring)
- {
- BOOST_ASSERT( boost::size(linestring) > 1 );
- return
- !geometry::equals(range::front(linestring),
- range::back(linestring))
- &&
- ( geometry::equals(point, range::front(linestring))
- || geometry::equals(point, range::back(linestring)) );
- }
+ BOOST_GEOMETRY_ASSERT(boost::size(linestring) > 1);
+ return
+ ! geometry::equals(range::front(linestring),
+ range::back(linestring))
+ &&
+ (geometry::equals(point, range::front(linestring))
+ || geometry::equals(point, range::back(linestring)));
+ }
+
+ template <typename Turn, typename Linestring>
+ static inline bool is_closing_point_of(Turn const& turn,
+ Linestring const& linestring)
+ {
+ BOOST_GEOMETRY_ASSERT(boost::size(linestring) > 1);
+ return
+ turn.method == overlay::method_none
+ &&
+ check_segment_indices(turn, boost::size(linestring) - 2)
+ &&
+ geometry::equals(range::front(linestring), range::back(linestring))
+ &&
+ turn.operations[0].fraction.is_zero();
+ ;
+ }
+
+ template <typename Linestring1, typename Linestring2>
+ static inline bool have_same_boundary_points(Linestring1 const& ls1,
+ Linestring2 const& ls2)
+ {
+ return
+ geometry::equals(range::front(ls1), range::front(ls2))
+ ?
+ geometry::equals(range::back(ls1), range::back(ls2))
+ :
+ (geometry::equals(range::front(ls1), range::back(ls2))
+ &&
+ geometry::equals(range::back(ls1), range::front(ls2)))
+ ;
+ }
+
+public:
+ is_acceptable_turn(MultiLinestring const& multilinestring)
+ : m_multilinestring(multilinestring)
+ {}
+
+ template <typename Turn>
+ inline bool apply(Turn const& turn) const
+ {
+ linestring_type const& ls1 =
+ range::at(m_multilinestring, turn.operations[0].seg_id.multi_index);
- template <typename Linestring1, typename Linestring2>
- static inline bool have_same_boundary_points(Linestring1 const& ls1,
- Linestring2 const& ls2)
+ linestring_type const& ls2 =
+ range::at(m_multilinestring, turn.operations[1].seg_id.multi_index);
+
+ if (turn.operations[0].seg_id.multi_index
+ == turn.operations[1].seg_id.multi_index)
{
- return
- geometry::equals(range::front(ls1), range::front(ls2))
- ?
- geometry::equals(range::back(ls1), range::back(ls2))
- :
- (geometry::equals(range::front(ls1), range::back(ls2))
- &&
- geometry::equals(range::back(ls1), range::front(ls2))
- )
- ;
+ return is_closing_point_of(turn, ls1);
}
- public:
- is_acceptable_turn(MultiLinestring const& multilinestring)
- : m_multilinestring(multilinestring)
- {}
+ return
+ is_boundary_point_of(turn.point, ls1)
+ && is_boundary_point_of(turn.point, ls2)
+ &&
+ ( boost::size(ls1) != 2
+ || boost::size(ls2) != 2
+ || ! have_same_boundary_points(ls1, ls2) );
+ }
- template <typename Turn>
- inline bool apply(Turn const& turn) const
- {
- typedef typename boost::range_value
+private:
+ MultiLinestring const& m_multilinestring;
+};
+
+
+template <typename Linear>
+inline bool has_self_intersections(Linear const& linear)
+{
+ typedef typename point_type<Linear>::type point_type;
+
+ // compute self turns
+ typedef detail::overlay::turn_info
+ <
+ point_type,
+ geometry::segment_ratio
<
- MultiLinestring
- >::type linestring;
-
- linestring const& ls1 =
- range::at(m_multilinestring,
- turn.operations[0].seg_id.multi_index);
-
- linestring const& ls2 =
- range::at(m_multilinestring,
- turn.operations[0].other_id.multi_index);
-
- return
- is_boundary_point_of(turn.point, ls1)
- && is_boundary_point_of(turn.point, ls2)
- &&
- ( boost::size(ls1) != 2
- || boost::size(ls2) != 2
- || !have_same_boundary_points(ls1, ls2) );
- }
+ typename geometry::coordinate_type<point_type>::type
+ >
+ > turn_info;
- private:
- MultiLinestring const& m_multilinestring;
- };
+ std::deque<turn_info> turns;
+ typedef detail::overlay::get_turn_info
+ <
+ detail::disjoint::assign_disjoint_policy
+ > turn_policy;
-public:
- static inline bool apply(MultiLinestring const& multilinestring)
+ is_acceptable_turn<Linear> predicate(linear);
+ detail::overlay::predicate_based_interrupt_policy
+ <
+ is_acceptable_turn<Linear>
+ > interrupt_policy(predicate);
+
+ detail::self_get_turn_points::get_turns
+ <
+ turn_policy
+ >::apply(linear,
+ detail::no_rescale_policy(),
+ turns,
+ interrupt_policy);
+
+ detail::is_valid::debug_print_turns(turns.begin(), turns.end());
+ debug_print_boundary_points(linear);
+
+ return interrupt_policy.has_intersections;
+}
+
+
+template <typename Linestring, bool CheckSelfIntersections = true>
+struct is_simple_linestring
+{
+ static inline bool apply(Linestring const& linestring)
{
- typedef typename boost::range_value<MultiLinestring>::type linestring;
- typedef typename point_type<MultiLinestring>::type point_type;
- typedef point_type point;
+ simplicity_failure_policy policy;
+ return ! detail::is_valid::has_duplicates
+ <
+ Linestring, closed
+ >::apply(linestring, policy)
+ && ! detail::is_valid::has_spikes
+ <
+ Linestring, closed
+ >::apply(linestring, policy)
+ && ! (CheckSelfIntersections && has_self_intersections(linestring));
+ }
+};
+template <typename MultiLinestring>
+struct is_simple_multilinestring
+{
+ static inline bool apply(MultiLinestring const& multilinestring)
+ {
// check each of the linestrings for simplicity
- if ( !detail::check_iterator_range
+ // but do not compute self-intersections yet; these will be
+ // computed for the entire multilinestring
+ if ( ! detail::check_iterator_range
<
- is_simple_linestring<linestring>,
+ is_simple_linestring
+ <
+ typename boost::range_value<MultiLinestring>::type,
+ false // do not compute self-intersections
+ >,
false // do not allow empty multilinestring
>::apply(boost::begin(multilinestring),
boost::end(multilinestring))
@@ -164,44 +271,8 @@ public:
return false;
}
-
- // compute self turns
- typedef detail::overlay::turn_info
- <
- point_type,
- geometry::segment_ratio
- <
- typename geometry::coordinate_type<point>::type
- >
- > turn_info;
-
- std::deque<turn_info> turns;
-
- typedef detail::overlay::get_turn_info
- <
- detail::disjoint::assign_disjoint_policy
- > turn_policy;
-
- is_acceptable_turn predicate(multilinestring);
- detail::overlay::predicate_based_interrupt_policy
- <
- is_acceptable_turn
- > interrupt_policy(predicate);
-
- detail::self_get_turn_points::get_turns
- <
- turn_policy
- >::apply(multilinestring,
- detail::no_rescale_policy(),
- turns,
- interrupt_policy);
-
- detail::is_valid::debug_print_turns(turns.begin(), turns.end());
- debug_print_boundary_points(multilinestring);
-
- return !interrupt_policy.has_intersections;
+ return ! has_self_intersections(multilinestring);
}
-
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_simple/multipoint.hpp b/3party/boost/boost/geometry/algorithms/detail/is_simple/multipoint.hpp
index d996eb64e9..71c9e6ba90 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_simple/multipoint.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_simple/multipoint.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -21,6 +21,7 @@
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp>
+#include <boost/geometry/algorithms/detail/is_simple/failure_policy.hpp>
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
@@ -48,7 +49,11 @@ struct is_simple_multipoint
std::sort(boost::begin(mp), boost::end(mp),
geometry::less<typename point_type<MultiPoint>::type>());
- return !detail::is_valid::has_duplicates<MultiPoint, closed>::apply(mp);
+ simplicity_failure_policy policy;
+ return !detail::is_valid::has_duplicates
+ <
+ MultiPoint, closed
+ >::apply(mp, policy);
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/box.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/box.hpp
index f82b3f9bf1..139502af78 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/box.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/box.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -16,6 +16,7 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
@@ -30,15 +31,22 @@ namespace detail { namespace is_valid
template <typename Box, std::size_t I>
struct has_valid_corners
{
- static inline bool apply(Box const& box)
+ template <typename VisitPolicy>
+ static inline bool apply(Box const& box, VisitPolicy& visitor)
{
- if ( geometry::get<geometry::max_corner, I-1>(box)
- <=
- geometry::get<geometry::min_corner, I-1>(box) )
+ if (math::equals(geometry::get<geometry::min_corner, I-1>(box),
+ geometry::get<geometry::max_corner, I-1>(box)))
{
- return false;
+ return
+ visitor.template apply<failure_wrong_topological_dimension>();
}
- return has_valid_corners<Box, I-1>::apply(box);
+ else if (geometry::get<geometry::min_corner, I-1>(box)
+ >
+ geometry::get<geometry::max_corner, I-1>(box))
+ {
+ return visitor.template apply<failure_wrong_corner_order>();
+ }
+ return has_valid_corners<Box, I-1>::apply(box, visitor);
}
};
@@ -46,9 +54,10 @@ struct has_valid_corners
template <typename Box>
struct has_valid_corners<Box, 0>
{
- static inline bool apply(Box const&)
+ template <typename VisitPolicy>
+ static inline bool apply(Box const&, VisitPolicy& visitor)
{
- return true;
+ return visitor.template apply<no_failure>();
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
index 2272bbf32f..07fe6a4c47 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
@@ -17,9 +17,9 @@
#include <utility>
#include <vector>
-#include <boost/assert.hpp>
#include <boost/core/addressof.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/policies/compare.hpp>
@@ -104,12 +104,12 @@ private:
, m_parent_id(num_nodes, -1)
{}
- inline int parent_id(vertex_handle v) const
+ inline signed_index_type parent_id(vertex_handle v) const
{
return m_parent_id[v->id()];
}
- inline void set_parent_id(vertex_handle v, int id)
+ inline void set_parent_id(vertex_handle v, signed_index_type id)
{
m_parent_id[v->id()] = id;
}
@@ -125,7 +125,7 @@ private:
}
private:
std::vector<bool> m_visited;
- std::vector<int> m_parent_id;
+ std::vector<signed_index_type> m_parent_id;
};
@@ -145,7 +145,7 @@ private:
= m_neighbors[v->id()].begin();
nit != m_neighbors[v->id()].end(); ++nit)
{
- if ( static_cast<int>((*nit)->id()) != data.parent_id(v) )
+ if ( static_cast<signed_index_type>((*nit)->id()) != data.parent_id(v) )
{
if ( data.visited(*nit) )
{
@@ -153,7 +153,7 @@ private:
}
else
{
- data.set_parent_id(*nit, static_cast<int>(v->id()));
+ data.set_parent_id(*nit, static_cast<signed_index_type>(v->id()));
stack.push(*nit);
}
}
@@ -173,7 +173,7 @@ public:
// inserts a ring vertex in the graph and returns its handle
// ring id's are zero-based (so the first interior ring has id 1)
- inline vertex_handle add_vertex(int id)
+ inline vertex_handle add_vertex(signed_index_type id)
{
return m_vertices.insert(vertex(static_cast<std::size_t>(id))).first;
}
@@ -197,8 +197,8 @@ public:
inline void add_edge(vertex_handle v1, vertex_handle v2)
{
- BOOST_ASSERT( v1 != m_vertices.end() );
- BOOST_ASSERT( v2 != m_vertices.end() );
+ BOOST_GEOMETRY_ASSERT( v1 != m_vertices.end() );
+ BOOST_GEOMETRY_ASSERT( v2 != m_vertices.end() );
m_neighbors[v1->id()].insert(v2);
m_neighbors[v2->id()].insert(v1);
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp
index b14355639d..ab99a9921b 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -25,33 +25,47 @@ namespace detail { namespace is_valid
{
#ifdef BOOST_GEOMETRY_TEST_DEBUG
+template <typename Turn>
+inline void debug_print_turn(Turn const& turn)
+{
+ std::cout << " ["
+ << geometry::method_char(turn.method)
+ << ","
+ << geometry::operation_char(turn.operations[0].operation)
+ << "/"
+ << geometry::operation_char(turn.operations[1].operation)
+ << " {"
+ << turn.operations[0].seg_id.multi_index
+ << ", "
+ << turn.operations[1].seg_id.multi_index
+ << "} {"
+ << turn.operations[0].seg_id.ring_index
+ << ", "
+ << turn.operations[1].seg_id.ring_index
+ << "} {"
+ << turn.operations[0].seg_id.segment_index
+ << ", "
+ << turn.operations[1].seg_id.segment_index
+ << "} "
+ << geometry::dsv(turn.point)
+ << "]";
+}
+
template <typename TurnIterator>
inline void debug_print_turns(TurnIterator first, TurnIterator beyond)
{
std::cout << "turns:";
for (TurnIterator tit = first; tit != beyond; ++tit)
{
- std::cout << " ["
- << geometry::method_char(tit->method)
- << ","
- << geometry::operation_char(tit->operations[0].operation)
- << "/"
- << geometry::operation_char(tit->operations[1].operation)
- << " {"
- << tit->operations[0].seg_id.multi_index
- << ", "
- << tit->operations[0].other_id.multi_index
- << "} {"
- << tit->operations[0].seg_id.ring_index
- << ", "
- << tit->operations[0].other_id.ring_index
- << "} "
- << geometry::dsv(tit->point)
- << "]";
+ debug_print_turn(*tit);
}
std::cout << std::endl << std::endl;
}
#else
+template <typename Turn>
+inline void debug_print_turn(Turn const&)
+{}
+
template <typename TurnIterator>
inline void debug_print_turns(TurnIterator, TurnIterator)
{}
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/debug_validity_phase.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/debug_validity_phase.hpp
index 6f1c263646..a10e0fe596 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/debug_validity_phase.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/debug_validity_phase.hpp
@@ -50,8 +50,8 @@ struct debug_validity_phase<Polygon, polygon_tag>
std::cout << "computing and analyzing turns..." << std::endl;
break;
case 4:
- std::cout << "checking if holes are inside the exterior ring..."
- << std::endl;
+ std::cout << "checking if interior rings are inside "
+ << "the exterior ring..." << std::endl;
break;
case 5:
std::cout << "checking connectivity of interior..." << std::endl;
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp
index dd0922bb2b..6aa8c98c9c 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -15,8 +15,10 @@
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/policies/compare.hpp>
+#include <boost/geometry/policies/is_valid/default_policy.hpp>
#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
namespace boost { namespace geometry
@@ -30,30 +32,35 @@ namespace detail { namespace is_valid
template <typename Range, closure_selector Closure>
struct has_duplicates
{
- static inline bool apply(Range const& range)
+ template <typename VisitPolicy>
+ static inline bool apply(Range const& range, VisitPolicy& visitor)
{
typedef typename closeable_view<Range const, Closure>::type view_type;
- typedef typename boost::range_iterator<view_type const>::type iterator;
+ typedef typename boost::range_const_iterator
+ <
+ view_type const
+ >::type const_iterator;
view_type view(range);
if ( boost::size(view) < 2 )
{
- return false;
+ return ! visitor.template apply<no_failure>();
}
geometry::equal_to<typename boost::range_value<Range>::type> equal;
- iterator it = boost::begin(view);
- iterator next = ++boost::begin(view);
- for (; next != boost::end(view); ++it, ++next)
+ const_iterator it = boost::const_begin(view);
+ const_iterator next = it;
+ ++next;
+ for (; next != boost::const_end(view); ++it, ++next)
{
if ( equal(*it, *next) )
{
- return true;
+ return ! visitor.template apply<failure_duplicate_points>(*it);
}
}
- return false;
+ return ! visitor.template apply<no_failure>();
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp
index 9b95017482..090c026e8b 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -13,15 +13,22 @@
#include <algorithm>
#include <boost/range.hpp>
+#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/policies/is_valid/default_policy.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp>
+#include <boost/geometry/io/dsv/write.hpp>
namespace boost { namespace geometry
@@ -60,7 +67,7 @@ struct not_equal_to
template <typename OtherPoint>
inline bool operator()(OtherPoint const& other) const
{
- return !geometry::equals(other, m_point);
+ return ! geometry::equals(other, m_point);
}
};
@@ -69,13 +76,17 @@ struct not_equal_to
template <typename Range, closure_selector Closure>
struct has_spikes
{
- static inline bool apply(Range const& range)
+ template <typename VisitPolicy>
+ static inline bool apply(Range const& range, VisitPolicy& visitor)
{
typedef not_equal_to<typename point_type<Range>::type> not_equal;
typedef typename closeable_view<Range const, Closure>::type view_type;
typedef typename boost::range_iterator<view_type const>::type iterator;
+ bool const is_linear
+ = boost::is_same<typename tag<Range>::type, linestring_tag>::value;
+
view_type const view(range);
iterator prev = boost::begin(view);
@@ -85,7 +96,7 @@ struct has_spikes
{
// the range has only one distinct point, so it
// cannot have a spike
- return false;
+ return ! visitor.template apply<no_failure>();
}
iterator next = std::find_if(cur, boost::end(view), not_equal(*cur));
@@ -93,7 +104,7 @@ struct has_spikes
{
// the range has only two distinct points, so it
// cannot have a spike
- return false;
+ return ! visitor.template apply<no_failure>();
}
while ( next != boost::end(view) )
@@ -102,7 +113,8 @@ struct has_spikes
*next,
*cur) )
{
- return true;
+ return
+ ! visitor.template apply<failure_spikes>(is_linear, *cur);
}
prev = cur;
cur = next;
@@ -120,10 +132,18 @@ struct has_spikes
not_equal(range::back(view)));
iterator next =
std::find_if(cur, boost::end(view), not_equal(*cur));
- return detail::point_is_spike_or_equal(*prev, *next, *cur);
+ if (detail::point_is_spike_or_equal(*prev, *next, *cur))
+ {
+ return
+ ! visitor.template apply<failure_spikes>(is_linear, *cur);
+ }
+ else
+ {
+ return ! visitor.template apply<no_failure>();
+ }
}
- return false;
+ return ! visitor.template apply<no_failure>();
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
index 220a67bcd1..ef1e9fc487 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -10,6 +10,11 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_VALID_SELF_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_VALID_SELF_TURNS_HPP
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/policies/predicate_based_interrupt_policy.hpp>
@@ -22,7 +27,6 @@
#include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp>
-
namespace boost { namespace geometry
{
@@ -64,8 +68,10 @@ public:
> turn_type;
// returns true if all turns are valid
- template <typename Turns>
- static inline bool apply(Geometry const& geometry, Turns& turns)
+ template <typename Turns, typename VisitPolicy>
+ static inline bool apply(Geometry const& geometry,
+ Turns& turns,
+ VisitPolicy& visitor)
{
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry);
@@ -80,7 +86,23 @@ public:
turns,
interrupt_policy);
- return !interrupt_policy.has_intersections;
+ if (interrupt_policy.has_intersections)
+ {
+ BOOST_GEOMETRY_ASSERT(! boost::empty(turns));
+ return visitor.template apply<failure_self_intersections>(turns);
+ }
+ else
+ {
+ return visitor.template apply<no_failure>();
+ }
+ }
+
+ // returns true if all turns are valid
+ template <typename VisitPolicy>
+ static inline bool apply(Geometry const& geometry, VisitPolicy& visitor)
+ {
+ std::vector<turn_type> turns;
+ return apply(geometry, turns, visitor);
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/interface.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/interface.hpp
index 4b232fd436..f83b09c437 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/interface.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/interface.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -10,13 +10,19 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_INTERFACE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_INTERFACE_HPP
-#include <boost/variant/static_visitor.hpp>
+#include <sstream>
+#include <string>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
+#include <boost/geometry/policies/is_valid/default_policy.hpp>
+#include <boost/geometry/policies/is_valid/failing_reason_policy.hpp>
+#include <boost/geometry/policies/is_valid/failure_type_policy.hpp>
namespace boost { namespace geometry
@@ -28,48 +34,123 @@ namespace resolve_variant {
template <typename Geometry>
struct is_valid
{
- static inline bool apply(Geometry const& geometry)
+ template <typename VisitPolicy>
+ static inline bool apply(Geometry const& geometry, VisitPolicy& visitor)
{
concept::check<Geometry const>();
- return dispatch::is_valid<Geometry>::apply(geometry);
+ return dispatch::is_valid<Geometry>::apply(geometry, visitor);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct is_valid<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
+ template <typename VisitPolicy>
struct visitor : boost::static_visitor<bool>
{
+ visitor(VisitPolicy& policy) : m_policy(policy) {}
+
template <typename Geometry>
bool operator()(Geometry const& geometry) const
{
- return is_valid<Geometry>::apply(geometry);
+ return is_valid<Geometry>::apply(geometry, m_policy);
}
+
+ VisitPolicy& m_policy;
};
+ template <typename VisitPolicy>
static inline bool
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+ VisitPolicy& policy_visitor)
{
- return boost::apply_visitor(visitor(), geometry);
+ return boost::apply_visitor(visitor<VisitPolicy>(policy_visitor),
+ geometry);
}
};
} // namespace resolve_variant
+// Undocumented for now
+template <typename Geometry, typename VisitPolicy>
+inline bool is_valid(Geometry const& geometry, VisitPolicy& visitor)
+{
+ return resolve_variant::is_valid<Geometry>::apply(geometry, visitor);
+}
+
+
/*!
\brief \brief_check{is valid (in the OGC sense)}
\ingroup is_valid
\tparam Geometry \tparam_geometry
\param geometry \param_geometry
-\return \return_check{is valid (in the OGC sense)}
+\return \return_check{is valid (in the OGC sense);
+ furthermore, the following geometries are considered valid:
+ multi-geometries with no elements,
+ linear geometries containing spikes,
+ areal geometries with duplicate (consecutive) points}
\qbk{[include reference/algorithms/is_valid.qbk]}
*/
template <typename Geometry>
inline bool is_valid(Geometry const& geometry)
{
- return resolve_variant::is_valid<Geometry>::apply(geometry);
+ is_valid_default_policy<> policy_visitor;
+ return is_valid(geometry, policy_visitor);
+}
+
+
+/*!
+\brief \brief_check{is valid (in the OGC sense)}
+\ingroup is_valid
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\param failure An enumeration value indicating that the geometry is
+ valid or not, and if not valid indicating the reason why
+\return \return_check{is valid (in the OGC sense);
+ furthermore, the following geometries are considered valid:
+ multi-geometries with no elements,
+ linear geometries containing spikes,
+ areal geometries with duplicate (consecutive) points}
+
+\qbk{distinguish,with failure value}
+\qbk{[include reference/algorithms/is_valid_with_failure.qbk]}
+*/
+template <typename Geometry>
+inline bool is_valid(Geometry const& geometry, validity_failure_type& failure)
+{
+ failure_type_policy<> policy_visitor;
+ bool result = is_valid(geometry, policy_visitor);
+ failure = policy_visitor.failure();
+ return result;
+}
+
+
+/*!
+\brief \brief_check{is valid (in the OGC sense)}
+\ingroup is_valid
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\param message A string containing a message stating if the geometry
+ is valid or not, and if not valid a reason why
+\return \return_check{is valid (in the OGC sense);
+ furthermore, the following geometries are considered valid:
+ multi-geometries with no elements,
+ linear geometries containing spikes,
+ areal geometries with duplicate (consecutive) points}
+
+\qbk{distinguish,with message}
+\qbk{[include reference/algorithms/is_valid_with_message.qbk]}
+*/
+template <typename Geometry>
+inline bool is_valid(Geometry const& geometry, std::string& message)
+{
+ std::ostringstream stream;
+ failing_reason_policy<> policy_visitor(stream);
+ bool result = is_valid(geometry, policy_visitor);
+ message = stream.str();
+ return result;
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp
index 9841aafd27..0d80d6f6c0 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -72,6 +72,16 @@ template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct is_acceptable_turn
{};
+template <typename Ring>
+struct is_acceptable_turn<Ring, ring_tag>
+{
+ template <typename Turn>
+ static inline bool apply(Turn const&)
+ {
+ return false;
+ }
+};
+
template <typename Polygon>
class is_acceptable_turn<Polygon, polygon_tag>
{
@@ -94,7 +104,7 @@ public:
using namespace detail::overlay;
if ( turn.operations[0].seg_id.ring_index
- == turn.operations[0].other_id.ring_index )
+ == turn.operations[1].seg_id.ring_index )
{
return false;
}
@@ -122,7 +132,7 @@ public:
using namespace detail::overlay;
if ( turn.operations[0].seg_id.multi_index
- == turn.operations[0].other_id.multi_index )
+ == turn.operations[1].seg_id.multi_index )
{
return base::apply(turn);
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/linear.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/linear.hpp
index 244df9b035..69243563ec 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/linear.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/linear.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -21,6 +21,7 @@
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp>
#include <boost/geometry/algorithms/detail/num_distinct_consecutive_points.hpp>
@@ -36,11 +37,18 @@ namespace detail { namespace is_valid
{
-template <typename Linestring, bool AllowSpikes>
+template <typename Linestring>
struct is_valid_linestring
{
- static inline bool apply(Linestring const& linestring)
+ template <typename VisitPolicy>
+ static inline bool apply(Linestring const& linestring,
+ VisitPolicy& visitor)
{
+ if (boost::size(linestring) < 2)
+ {
+ return visitor.template apply<failure_few_points>();
+ }
+
std::size_t num_distinct = detail::num_distinct_consecutive_points
<
Linestring,
@@ -49,14 +57,17 @@ struct is_valid_linestring
not_equal_to<typename point_type<Linestring>::type>
>::apply(linestring);
- if ( num_distinct < 2u )
+ if (num_distinct < 2u)
{
- return false;
+ return
+ visitor.template apply<failure_wrong_topological_dimension>();
}
- return num_distinct == 2u
- || AllowSpikes
- || !has_spikes<Linestring, closed>::apply(linestring);
+ if (num_distinct == 2u)
+ {
+ return visitor.template apply<no_failure>();
+ }
+ return ! has_spikes<Linestring, closed>::apply(linestring, visitor);
}
};
@@ -84,9 +95,11 @@ namespace dispatch
// By default, spikes are disallowed
//
// Reference: OGC 06-103r4 (6.1.6.1)
-template <typename Linestring, bool AllowSpikes>
-struct is_valid<Linestring, linestring_tag, AllowSpikes>
- : detail::is_valid::is_valid_linestring<Linestring, AllowSpikes>
+template <typename Linestring, bool AllowEmptyMultiGeometries>
+struct is_valid
+ <
+ Linestring, linestring_tag, AllowEmptyMultiGeometries
+ > : detail::is_valid::is_valid_linestring<Linestring>
{};
@@ -96,21 +109,47 @@ struct is_valid<Linestring, linestring_tag, AllowSpikes>
// are on the boundaries of both elements.
//
// Reference: OGC 06-103r4 (6.1.8.1; Fig. 9)
-template <typename MultiLinestring, bool AllowSpikes>
-struct is_valid<MultiLinestring, multi_linestring_tag, AllowSpikes>
+template <typename MultiLinestring, bool AllowEmptyMultiGeometries>
+class is_valid
+ <
+ MultiLinestring, multi_linestring_tag, AllowEmptyMultiGeometries
+ >
{
- static inline bool apply(MultiLinestring const& multilinestring)
+private:
+ template <typename VisitPolicy>
+ struct per_linestring
+ {
+ per_linestring(VisitPolicy& policy) : m_policy(policy) {}
+
+ template <typename Linestring>
+ inline bool apply(Linestring const& linestring) const
+ {
+ return detail::is_valid::is_valid_linestring
+ <
+ Linestring
+ >::apply(linestring, m_policy);
+ }
+
+ VisitPolicy& m_policy;
+ };
+
+public:
+ template <typename VisitPolicy>
+ static inline bool apply(MultiLinestring const& multilinestring,
+ VisitPolicy& visitor)
{
+ if (AllowEmptyMultiGeometries && boost::empty(multilinestring))
+ {
+ return visitor.template apply<no_failure>();
+ }
+
return detail::check_iterator_range
<
- detail::is_valid::is_valid_linestring
- <
- typename boost::range_value<MultiLinestring>::type,
- AllowSpikes
- >,
- false // do not allow empty multilinestring
+ per_linestring<VisitPolicy>,
+ false // do not check for empty multilinestring (done above)
>::apply(boost::begin(multilinestring),
- boost::end(multilinestring));
+ boost::end(multilinestring),
+ per_linestring<VisitPolicy>(visitor));
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
index 373825f232..9362bfca0e 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -11,6 +11,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_MULTIPOLYGON_HPP
#include <deque>
+#include <vector>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range.hpp>
@@ -22,9 +23,13 @@
#include <boost/geometry/util/range.hpp>
+#include <boost/geometry/geometries/box.hpp>
+
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp>
#include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp>
@@ -45,12 +50,11 @@ namespace detail { namespace is_valid
{
-template <typename MultiPolygon, bool AllowDuplicates>
+template <typename MultiPolygon, bool AllowEmptyMultiGeometries>
class is_valid_multipolygon
: is_valid_polygon
<
typename boost::range_value<MultiPolygon>::type,
- AllowDuplicates,
true // check only the validity of rings
>
{
@@ -58,48 +62,61 @@ private:
typedef is_valid_polygon
<
typename boost::range_value<MultiPolygon>::type,
- AllowDuplicates,
true
> base;
- template <typename PolygonIterator, typename TurnIterator>
+ template
+ <
+ typename PolygonIterator,
+ typename TurnIterator,
+ typename VisitPolicy
+ >
static inline
bool are_polygon_interiors_disjoint(PolygonIterator polygons_first,
PolygonIterator polygons_beyond,
TurnIterator turns_first,
- TurnIterator turns_beyond)
+ TurnIterator turns_beyond,
+ VisitPolicy& visitor)
{
- std::set<int> multi_indices;
+ // collect all polygons that have turns
+ std::set<signed_index_type> multi_indices;
for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit)
{
multi_indices.insert(tit->operations[0].seg_id.multi_index);
- multi_indices.insert(tit->operations[0].other_id.multi_index);
+ multi_indices.insert(tit->operations[1].seg_id.multi_index);
}
- int multi_index = 0;
- for (PolygonIterator it1 = polygons_first; it1 != polygons_beyond;
- ++it1, ++multi_index)
+ // put polygon iterators without turns in a vector
+ std::vector<PolygonIterator> polygon_iterators;
+ signed_index_type multi_index = 0;
+ for (PolygonIterator it = polygons_first; it != polygons_beyond;
+ ++it, ++multi_index)
{
- if ( multi_indices.find(multi_index) != multi_indices.end() )
+ if (multi_indices.find(multi_index) == multi_indices.end())
{
- continue;
+ polygon_iterators.push_back(it);
}
+ }
- for (PolygonIterator it2 = polygons_first;
- it2 != polygons_beyond; ++it2)
- {
- if ( it1 != it2
- &&
- geometry::within(range::front(exterior_ring(*it1)), *it2)
- )
- {
- return false;
- }
- }
+ typename base::item_visitor_type item_visitor;
+
+ geometry::partition
+ <
+ geometry::model::box<typename point_type<MultiPolygon>::type>,
+ typename base::expand_box,
+ typename base::overlaps_box
+ >::apply(polygon_iterators, item_visitor);
+
+ if (item_visitor.items_overlap)
+ {
+ return visitor.template apply<failure_intersecting_interiors>();
+ }
+ else
+ {
+ return visitor.template apply<no_failure>();
}
- return true;
}
@@ -107,7 +124,7 @@ private:
class has_multi_index
{
public:
- has_multi_index(int multi_index)
+ has_multi_index(signed_index_type multi_index)
: m_multi_index(multi_index)
{}
@@ -115,11 +132,11 @@ private:
inline bool operator()(Turn const& turn) const
{
return turn.operations[0].seg_id.multi_index == m_multi_index
- && turn.operations[0].other_id.multi_index == m_multi_index;
+ && turn.operations[1].seg_id.multi_index == m_multi_index;
}
private:
- int const m_multi_index;
+ signed_index_type const m_multi_index;
};
@@ -127,13 +144,19 @@ private:
template <typename Predicate>
struct has_property_per_polygon
{
- template <typename PolygonIterator, typename TurnIterator>
+ template
+ <
+ typename PolygonIterator,
+ typename TurnIterator,
+ typename VisitPolicy
+ >
static inline bool apply(PolygonIterator polygons_first,
PolygonIterator polygons_beyond,
TurnIterator turns_first,
- TurnIterator turns_beyond)
+ TurnIterator turns_beyond,
+ VisitPolicy& visitor)
{
- int multi_index = 0;
+ signed_index_type multi_index = 0;
for (PolygonIterator it = polygons_first; it != polygons_beyond;
++it, ++multi_index)
{
@@ -152,9 +175,10 @@ private:
turns_beyond,
turns_beyond);
- if ( !Predicate::apply(*it,
+ if (! Predicate::apply(*it,
filtered_turns_first,
- filtered_turns_beyond) )
+ filtered_turns_beyond,
+ visitor))
{
return false;
}
@@ -165,49 +189,82 @@ private:
- template <typename PolygonIterator, typename TurnIterator>
+ template
+ <
+ typename PolygonIterator,
+ typename TurnIterator,
+ typename VisitPolicy
+ >
static inline bool have_holes_inside(PolygonIterator polygons_first,
PolygonIterator polygons_beyond,
TurnIterator turns_first,
- TurnIterator turns_beyond)
+ TurnIterator turns_beyond,
+ VisitPolicy& visitor)
{
return has_property_per_polygon
<
typename base::has_holes_inside
>::apply(polygons_first, polygons_beyond,
- turns_first, turns_beyond);
+ turns_first, turns_beyond, visitor);
}
- template <typename PolygonIterator, typename TurnIterator>
+ template
+ <
+ typename PolygonIterator,
+ typename TurnIterator,
+ typename VisitPolicy
+ >
static inline bool have_connected_interior(PolygonIterator polygons_first,
PolygonIterator polygons_beyond,
TurnIterator turns_first,
- TurnIterator turns_beyond)
+ TurnIterator turns_beyond,
+ VisitPolicy& visitor)
{
return has_property_per_polygon
<
typename base::has_connected_interior
>::apply(polygons_first, polygons_beyond,
- turns_first, turns_beyond);
+ turns_first, turns_beyond, visitor);
}
+ template <typename VisitPolicy>
+ struct per_polygon
+ {
+ per_polygon(VisitPolicy& policy) : m_policy(policy) {}
+
+ template <typename Polygon>
+ inline bool apply(Polygon const& polygon) const
+ {
+ return base::apply(polygon, m_policy);
+ }
+
+ VisitPolicy& m_policy;
+ };
public:
- static inline bool apply(MultiPolygon const& multipolygon)
+ template <typename VisitPolicy>
+ static inline bool apply(MultiPolygon const& multipolygon,
+ VisitPolicy& visitor)
{
typedef debug_validity_phase<MultiPolygon> debug_phase;
+ if (AllowEmptyMultiGeometries && boost::empty(multipolygon))
+ {
+ return visitor.template apply<no_failure>();
+ }
+
// check validity of all polygons ring
debug_phase::apply(1);
- if ( !detail::check_iterator_range
+ if (! detail::check_iterator_range
<
- base,
- false // do not allow empty multi-polygons
+ per_polygon<VisitPolicy>,
+ false // do not check for empty multipolygon (done above)
>::apply(boost::begin(multipolygon),
- boost::end(multipolygon)) )
+ boost::end(multipolygon),
+ per_polygon<VisitPolicy>(visitor)))
{
return false;
}
@@ -219,10 +276,11 @@ public:
typedef has_valid_self_turns<MultiPolygon> has_valid_turns;
std::deque<typename has_valid_turns::turn_type> turns;
- bool has_invalid_turns = !has_valid_turns::apply(multipolygon, turns);
+ bool has_invalid_turns =
+ ! has_valid_turns::apply(multipolygon, turns, visitor);
debug_print_turns(turns.begin(), turns.end());
- if ( has_invalid_turns )
+ if (has_invalid_turns)
{
return false;
}
@@ -232,10 +290,11 @@ public:
// exterior and not one inside the other
debug_phase::apply(3);
- if ( !have_holes_inside(boost::begin(multipolygon),
+ if (! have_holes_inside(boost::begin(multipolygon),
boost::end(multipolygon),
turns.begin(),
- turns.end()) )
+ turns.end(),
+ visitor))
{
return false;
}
@@ -244,10 +303,11 @@ public:
// check that each polygon's interior is connected
debug_phase::apply(4);
- if ( !have_connected_interior(boost::begin(multipolygon),
+ if (! have_connected_interior(boost::begin(multipolygon),
boost::end(multipolygon),
turns.begin(),
- turns.end()) )
+ turns.end(),
+ visitor))
{
return false;
}
@@ -258,7 +318,8 @@ public:
return are_polygon_interiors_disjoint(boost::begin(multipolygon),
boost::end(multipolygon),
turns.begin(),
- turns.end());
+ turns.end(),
+ visitor);
}
};
@@ -277,9 +338,14 @@ namespace dispatch
// that the MultiPolygon is also valid.
//
// Reference (for validity of MultiPolygons): OGC 06-103r4 (6.1.14)
-template <typename MultiPolygon, bool AllowSpikes, bool AllowDuplicates>
-struct is_valid<MultiPolygon, multi_polygon_tag, AllowSpikes, AllowDuplicates>
- : detail::is_valid::is_valid_multipolygon<MultiPolygon, AllowDuplicates>
+template <typename MultiPolygon, bool AllowEmptyMultiGeometries>
+struct is_valid
+ <
+ MultiPolygon, multi_polygon_tag, AllowEmptyMultiGeometries
+ > : detail::is_valid::is_valid_multipolygon
+ <
+ MultiPolygon, AllowEmptyMultiGeometries
+ >
{};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/pointlike.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
index 8a4818ef15..8e5ebaadcc 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -14,6 +14,7 @@
#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
@@ -30,9 +31,10 @@ namespace dispatch
template <typename Point>
struct is_valid<Point, point_tag>
{
- static inline bool apply(Point const&)
+ template <typename VisitPolicy>
+ static inline bool apply(Point const&, VisitPolicy& visitor)
{
- return true;
+ return visitor.template apply<no_failure>();
}
};
@@ -42,12 +44,24 @@ struct is_valid<Point, point_tag>
// (have identical coordinate values in X and Y)
//
// Reference: OGC 06-103r4 (6.1.5)
-template <typename MultiPoint>
-struct is_valid<MultiPoint, multi_point_tag>
+template <typename MultiPoint, bool AllowEmptyMultiGeometries>
+struct is_valid<MultiPoint, multi_point_tag, AllowEmptyMultiGeometries>
{
- static inline bool apply(MultiPoint const& multipoint)
+ template <typename VisitPolicy>
+ static inline bool apply(MultiPoint const& multipoint,
+ VisitPolicy& visitor)
{
- return boost::size(multipoint) > 0;
+ if (AllowEmptyMultiGeometries || boost::size(multipoint) > 0)
+ {
+ // we allow empty multi-geometries, so an empty multipoint
+ // is considered valid
+ return visitor.template apply<no_failure>();
+ }
+ else
+ {
+ // we do not allow an empty multipoint
+ return visitor.template apply<failure_few_points>();
+ }
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/polygon.hpp
index 268b8975e2..eb5d62e033 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/polygon.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/polygon.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -16,22 +16,32 @@
#include <deque>
#include <iterator>
#include <set>
+#include <vector>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.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/tags.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
+#include <boost/geometry/geometries/box.hpp>
+
+#include <boost/geometry/iterators/point_iterator.hpp>
+
#include <boost/geometry/algorithms/covered_by.hpp>
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/is_valid/complement_graph.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp>
@@ -54,51 +64,58 @@ namespace detail { namespace is_valid
{
-template
-<
- typename Polygon,
- bool AllowDuplicates,
- bool CheckRingValidityOnly = false
->
+template <typename Polygon, bool CheckRingValidityOnly = false>
class is_valid_polygon
{
protected:
typedef debug_validity_phase<Polygon> debug_phase;
+ template <typename VisitPolicy>
+ struct per_ring
+ {
+ per_ring(VisitPolicy& policy) : m_policy(policy) {}
+ template <typename Ring>
+ inline bool apply(Ring const& ring) const
+ {
+ return detail::is_valid::is_valid_ring
+ <
+ Ring, false, true
+ >::apply(ring, m_policy);
+ }
- template <typename InteriorRings>
- static bool has_valid_interior_rings(InteriorRings const& interior_rings)
+ VisitPolicy& m_policy;
+ };
+
+ template <typename InteriorRings, typename VisitPolicy>
+ static bool has_valid_interior_rings(InteriorRings const& interior_rings,
+ VisitPolicy& visitor)
{
return
detail::check_iterator_range
<
- detail::is_valid::is_valid_ring
- <
- typename boost::range_value<InteriorRings>::type,
- AllowDuplicates,
- false, // do not check self-intersections
- true // indicate that the ring is interior
- >
+ per_ring<VisitPolicy>,
+ true // allow for empty interior ring range
>::apply(boost::begin(interior_rings),
- boost::end(interior_rings));
+ boost::end(interior_rings),
+ per_ring<VisitPolicy>(visitor));
}
struct has_valid_rings
{
- static inline bool apply(Polygon const& polygon)
+ template <typename VisitPolicy>
+ static inline bool apply(Polygon const& polygon, VisitPolicy& visitor)
{
typedef typename ring_type<Polygon>::type ring_type;
// check validity of exterior ring
debug_phase::apply(1);
- if ( !detail::is_valid::is_valid_ring
+ if (! detail::is_valid::is_valid_ring
<
ring_type,
- AllowDuplicates,
false // do not check self intersections
- >::apply(exterior_ring(polygon)) )
+ >::apply(exterior_ring(polygon), visitor))
{
return false;
}
@@ -106,52 +123,95 @@ protected:
// check validity of interior rings
debug_phase::apply(2);
- return has_valid_interior_rings(geometry::interior_rings(polygon));
+ return has_valid_interior_rings(geometry::interior_rings(polygon),
+ visitor);
+ }
+ };
+
+
+ // structs for partition -- start
+ struct expand_box
+ {
+ template <typename Box, typename Iterator>
+ static inline void apply(Box& total, Iterator const& it)
+ {
+ geometry::expand(total, geometry::return_envelope<Box>(*it));
}
+
};
+ struct overlaps_box
+ {
+ template <typename Box, typename Iterator>
+ static inline bool apply(Box const& box, Iterator const& it)
+ {
+ return ! geometry::disjoint(*it, box);
+ }
+ };
+ struct item_visitor_type
+ {
+ bool items_overlap;
+
+ item_visitor_type() : items_overlap(false) {}
+
+ template <typename Item1, typename Item2>
+ inline void apply(Item1 const& item1, Item2 const& item2)
+ {
+ if (! items_overlap
+ && (geometry::within(*points_begin(*item1), *item2)
+ || geometry::within(*points_begin(*item2), *item1))
+ )
+ {
+ items_overlap = true;
+ }
+ }
+ };
+ // structs for partition -- end
+
template
<
typename RingIterator,
typename ExteriorRing,
- typename TurnIterator
+ typename TurnIterator,
+ typename VisitPolicy
>
static inline bool are_holes_inside(RingIterator rings_first,
RingIterator rings_beyond,
ExteriorRing const& exterior_ring,
TurnIterator turns_first,
- TurnIterator turns_beyond)
+ TurnIterator turns_beyond,
+ VisitPolicy& visitor)
{
// collect the interior ring indices that have turns with the
// exterior ring
- std::set<int> ring_indices;
+ std::set<signed_index_type> ring_indices;
for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit)
{
- if ( tit->operations[0].seg_id.ring_index == -1 )
+ if (tit->operations[0].seg_id.ring_index == -1)
{
- BOOST_ASSERT( tit->operations[0].other_id.ring_index != -1 );
- ring_indices.insert(tit->operations[0].other_id.ring_index);
+ BOOST_GEOMETRY_ASSERT(tit->operations[1].seg_id.ring_index != -1);
+ ring_indices.insert(tit->operations[1].seg_id.ring_index);
}
- else if ( tit->operations[0].other_id.ring_index == -1 )
+ else if (tit->operations[1].seg_id.ring_index == -1)
{
- BOOST_ASSERT( tit->operations[0].seg_id.ring_index != -1 );
+ BOOST_GEOMETRY_ASSERT(tit->operations[0].seg_id.ring_index != -1);
ring_indices.insert(tit->operations[0].seg_id.ring_index);
}
}
- int ring_index = 0;
+ signed_index_type ring_index = 0;
for (RingIterator it = rings_first; it != rings_beyond;
++it, ++ring_index)
{
// do not examine interior rings that have turns with the
// exterior ring
- if ( ring_indices.find(ring_index) == ring_indices.end()
- && !geometry::covered_by(range::front(*it), exterior_ring) )
+ if (ring_indices.find(ring_index) == ring_indices.end()
+ && ! geometry::covered_by(range::front(*it), exterior_ring))
{
- return false;
+ return visitor.template apply<failure_interior_rings_outside>();
}
}
@@ -159,58 +219,76 @@ protected:
for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit)
{
ring_indices.insert(tit->operations[0].seg_id.ring_index);
- ring_indices.insert(tit->operations[0].other_id.ring_index);
+ ring_indices.insert(tit->operations[1].seg_id.ring_index);
}
+ // put iterators for interior rings without turns in a vector
+ std::vector<RingIterator> ring_iterators;
ring_index = 0;
- for (RingIterator it1 = rings_first; it1 != rings_beyond;
- ++it1, ++ring_index)
+ for (RingIterator it = rings_first; it != rings_beyond;
+ ++it, ++ring_index)
{
- // do not examine rings that are associated with turns
- if ( ring_indices.find(ring_index) == ring_indices.end() )
+ if (ring_indices.find(ring_index) == ring_indices.end())
{
- for (RingIterator it2 = rings_first; it2 != rings_beyond; ++it2)
- {
- if ( it1 != it2
- && geometry::within(range::front(*it1), *it2) )
- {
- return false;
- }
- }
+ ring_iterators.push_back(it);
}
}
- return true;
+
+ // call partition to check is interior rings are disjoint from
+ // each other
+ item_visitor_type item_visitor;
+
+ geometry::partition
+ <
+ geometry::model::box<typename point_type<Polygon>::type>,
+ expand_box,
+ overlaps_box
+ >::apply(ring_iterators, item_visitor);
+
+ if (item_visitor.items_overlap)
+ {
+ return visitor.template apply<failure_nested_interior_rings>();
+ }
+ else
+ {
+ return visitor.template apply<no_failure>();
+ }
}
template
<
typename InteriorRings,
typename ExteriorRing,
- typename TurnIterator
+ typename TurnIterator,
+ typename VisitPolicy
>
static inline bool are_holes_inside(InteriorRings const& interior_rings,
ExteriorRing const& exterior_ring,
TurnIterator first,
- TurnIterator beyond)
+ TurnIterator beyond,
+ VisitPolicy& visitor)
{
return are_holes_inside(boost::begin(interior_rings),
boost::end(interior_rings),
exterior_ring,
first,
- beyond);
+ beyond,
+ visitor);
}
struct has_holes_inside
{
- template <typename TurnIterator>
+ template <typename TurnIterator, typename VisitPolicy>
static inline bool apply(Polygon const& polygon,
TurnIterator first,
- TurnIterator beyond)
+ TurnIterator beyond,
+ VisitPolicy& visitor)
{
return are_holes_inside(geometry::interior_rings(polygon),
geometry::exterior_ring(polygon),
first,
- beyond);
+ beyond,
+ visitor);
}
};
@@ -219,10 +297,11 @@ protected:
struct has_connected_interior
{
- template <typename TurnIterator>
+ template <typename TurnIterator, typename VisitPolicy>
static inline bool apply(Polygon const& polygon,
TurnIterator first,
- TurnIterator beyond)
+ TurnIterator beyond,
+ VisitPolicy& visitor)
{
typedef typename std::iterator_traits
<
@@ -236,7 +315,7 @@ protected:
typename graph::vertex_handle v1 = g.add_vertex
( tit->operations[0].seg_id.ring_index + 1 );
typename graph::vertex_handle v2 = g.add_vertex
- ( tit->operations[0].other_id.ring_index + 1 );
+ ( tit->operations[1].seg_id.ring_index + 1 );
typename graph::vertex_handle vip = g.add_vertex(tit->point);
g.add_edge(v1, vip);
@@ -245,19 +324,27 @@ protected:
debug_print_complement_graph(std::cout, g);
- return !g.has_cycles();
+ if (g.has_cycles())
+ {
+ return visitor.template apply<failure_disconnected_interior>();
+ }
+ else
+ {
+ return visitor.template apply<no_failure>();
+ }
}
};
public:
- static inline bool apply(Polygon const& polygon)
+ template <typename VisitPolicy>
+ static inline bool apply(Polygon const& polygon, VisitPolicy& visitor)
{
- if ( !has_valid_rings::apply(polygon) )
+ if (! has_valid_rings::apply(polygon, visitor))
{
return false;
}
- if ( CheckRingValidityOnly )
+ if (BOOST_GEOMETRY_CONDITION(CheckRingValidityOnly))
{
return true;
}
@@ -268,10 +355,11 @@ public:
typedef has_valid_self_turns<Polygon> has_valid_turns;
std::deque<typename has_valid_turns::turn_type> turns;
- bool has_invalid_turns = !has_valid_turns::apply(polygon, turns);
+ bool has_invalid_turns
+ = ! has_valid_turns::apply(polygon, turns, visitor);
debug_print_turns(turns.begin(), turns.end());
- if ( has_invalid_turns )
+ if (has_invalid_turns)
{
return false;
}
@@ -279,7 +367,9 @@ public:
// check if all interior rings are inside the exterior ring
debug_phase::apply(4);
- if ( !has_holes_inside::apply(polygon, turns.begin(), turns.end()) )
+ if (! has_holes_inside::apply(polygon,
+ turns.begin(), turns.end(),
+ visitor))
{
return false;
}
@@ -289,7 +379,8 @@ public:
return has_connected_interior::apply(polygon,
turns.begin(),
- turns.end());
+ turns.end(),
+ visitor);
}
};
@@ -307,9 +398,11 @@ namespace dispatch
// A Polygon is always a simple geometric object provided that it is valid.
//
// Reference (for validity of Polygons): OGC 06-103r4 (6.1.11.1)
-template <typename Polygon, bool AllowSpikes, bool AllowDuplicates>
-struct is_valid<Polygon, polygon_tag, AllowSpikes, AllowDuplicates>
- : detail::is_valid::is_valid_polygon<Polygon, AllowDuplicates>
+template <typename Polygon, bool AllowEmptyMultiGeometries>
+struct is_valid
+ <
+ Polygon, polygon_tag, AllowEmptyMultiGeometries
+ > : detail::is_valid::is_valid_polygon<Polygon>
{};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/ring.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/ring.hpp
index c88df79b05..c663a96d28 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/ring.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/ring.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -10,6 +10,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_RING_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_RING_HPP
+#include <deque>
+
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_order.hpp>
@@ -19,16 +21,22 @@
#include <boost/geometry/algorithms/equals.hpp>
-#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
+#include <boost/geometry/algorithms/detail/num_distinct_consecutive_points.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp>
+#include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp>
#include <boost/geometry/strategies/area.hpp>
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+#include <boost/geometry/io/dsv/write.hpp>
+#endif
+
namespace boost { namespace geometry
{
@@ -42,18 +50,27 @@ namespace detail { namespace is_valid
template <typename Ring, closure_selector Closure /* open */>
struct is_topologically_closed
{
- static inline bool apply(Ring const&)
+ template <typename VisitPolicy>
+ static inline bool apply(Ring const&, VisitPolicy& visitor)
{
- return true;
+ return visitor.template apply<no_failure>();
}
};
template <typename Ring>
struct is_topologically_closed<Ring, closed>
{
- static inline bool apply(Ring const& ring)
+ template <typename VisitPolicy>
+ static inline bool apply(Ring const& ring, VisitPolicy& visitor)
{
- return geometry::equals(range::front(ring), range::back(ring));
+ if (geometry::equals(range::front(ring), range::back(ring)))
+ {
+ return visitor.template apply<no_failure>();
+ }
+ else
+ {
+ return visitor.template apply<failure_not_closed>();
+ }
}
};
@@ -92,7 +109,8 @@ struct is_properly_oriented
typedef typename default_area_result<Ring>::type area_result_type;
- static inline bool apply(Ring const& ring)
+ template <typename VisitPolicy>
+ static inline bool apply(Ring const& ring, VisitPolicy& visitor)
{
typename ring_area_predicate
<
@@ -101,7 +119,14 @@ struct is_properly_oriented
// Check area
area_result_type const zero = area_result_type();
- return predicate(ring_area_type::apply(ring, strategy_type()), zero);
+ if (predicate(ring_area_type::apply(ring, strategy_type()), zero))
+ {
+ return visitor.template apply<no_failure>();
+ }
+ else
+ {
+ return visitor.template apply<failure_wrong_orientation>();
+ }
}
};
@@ -110,41 +135,60 @@ struct is_properly_oriented
template
<
typename Ring,
- bool AllowDuplicates,
bool CheckSelfIntersections = true,
bool IsInteriorRing = false
>
struct is_valid_ring
{
- static inline bool apply(Ring const& ring)
+ template <typename VisitPolicy>
+ static inline bool apply(Ring const& ring, VisitPolicy& visitor)
{
// return invalid if any of the following condition holds:
// (a) the ring's size is below the minimal one
- // (b) the ring is not topologically closed
- // (c) the ring has spikes
- // (d) the ring has duplicate points (if AllowDuplicates is false)
- // (e) the boundary of the ring has self-intersections
- // (f) the order of the points is inconsistent with the defined order
+ // (b) the ring consists of at most two distinct points
+ // (c) the ring is not topologically closed
+ // (d) the ring has spikes
+ // (e) the ring has duplicate points (if AllowDuplicates is false)
+ // (f) the boundary of the ring has self-intersections
+ // (g) the order of the points is inconsistent with the defined order
//
// Note: no need to check if the area is zero. If this is the
// case, then the ring must have at least two spikes, which is
// checked by condition (c).
closure_selector const closure = geometry::closure<Ring>::value;
+ typedef typename closeable_view<Ring const, closure>::type view_type;
+
+ if (boost::size(ring)
+ < core_detail::closure::minimum_ring_size<closure>::value)
+ {
+ return visitor.template apply<failure_few_points>();
+ }
+
+ view_type const view(ring);
+ if (detail::num_distinct_consecutive_points
+ <
+ view_type, 4u, true,
+ not_equal_to<typename point_type<Ring>::type>
+ >::apply(view)
+ < 4u)
+ {
+ return
+ visitor.template apply<failure_wrong_topological_dimension>();
+ }
return
- ( boost::size(ring)
- >= core_detail::closure::minimum_ring_size<closure>::value )
- && is_topologically_closed<Ring, closure>::apply(ring)
- && (AllowDuplicates || !has_duplicates<Ring, closure>::apply(ring))
- && !has_spikes<Ring, closure>::apply(ring)
- && !(CheckSelfIntersections && geometry::intersects(ring))
- && is_properly_oriented<Ring, IsInteriorRing>::apply(ring);
+ is_topologically_closed<Ring, closure>::apply(ring, visitor)
+ && ! has_duplicates<Ring, closure>::apply(ring, visitor)
+ && ! has_spikes<Ring, closure>::apply(ring, visitor)
+ && (! CheckSelfIntersections
+ || has_valid_self_turns<Ring>::apply(ring, visitor))
+ && is_properly_oriented<Ring, IsInteriorRing>::apply(ring, visitor);
}
};
-}} // namespace dispatch
+}} // namespace detail::is_valid
#endif // DOXYGEN_NO_DETAIL
@@ -158,9 +202,11 @@ namespace dispatch
// 6.1.7.1, for the definition of LinearRing)
//
// Reference (for polygon validity): OGC 06-103r4 (6.1.11.1)
-template <typename Ring, bool AllowSpikes, bool AllowDuplicates>
-struct is_valid<Ring, ring_tag, AllowSpikes, AllowDuplicates>
- : detail::is_valid::is_valid_ring<Ring, AllowDuplicates>
+template <typename Ring, bool AllowEmptyMultiGeometries>
+struct is_valid
+ <
+ Ring, ring_tag, AllowEmptyMultiGeometries
+ > : detail::is_valid::is_valid_ring<Ring>
{};
diff --git a/3party/boost/boost/geometry/algorithms/detail/is_valid/segment.hpp b/3party/boost/boost/geometry/algorithms/detail/is_valid/segment.hpp
index 486289dabe..0b60890dc0 100644
--- a/3party/boost/boost/geometry/algorithms/detail/is_valid/segment.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/is_valid/segment.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -15,6 +15,7 @@
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
@@ -40,13 +41,22 @@ namespace dispatch
template <typename Segment>
struct is_valid<Segment, segment_tag>
{
- static inline bool apply(Segment const& segment)
+ template <typename VisitPolicy>
+ static inline bool apply(Segment const& segment, VisitPolicy& visitor)
{
typename point_type<Segment>::type p[2];
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
- return !geometry::equals(p[0], p[1]);
+ if(! geometry::equals(p[0], p[1]))
+ {
+ return visitor.template apply<no_failure>();
+ }
+ else
+ {
+ return
+ visitor.template apply<failure_wrong_topological_dimension>();
+ }
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/max_interval_gap.hpp b/3party/boost/boost/geometry/algorithms/detail/max_interval_gap.hpp
new file mode 100644
index 0000000000..e8a70a6b5f
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/max_interval_gap.hpp
@@ -0,0 +1,278 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_MAX_INTERVAL_GAP_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_MAX_INTERVAL_GAP_HPP
+
+#include <cstddef>
+#include <queue>
+#include <utility>
+#include <vector>
+
+#include <boost/core/ref.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/algorithms/detail/sweep.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace max_interval_gap
+{
+
+// the class Interval must provide the following:
+// * must define the type value_type
+// * must define the type difference_type
+// * must have the methods:
+// value_type get<Index>() const
+// difference_type length() const
+// where an Index value of 0 (resp., 1) refers to the left (resp.,
+// right) endpoint of the interval
+
+template <typename Interval>
+class sweep_event
+{
+public:
+ typedef Interval interval_type;
+ typedef typename Interval::value_type time_type;
+
+ sweep_event(Interval const& interval, bool start_event = true)
+ : m_interval(boost::cref(interval))
+ , m_start_event(start_event)
+ {}
+
+ inline bool is_start_event() const
+ {
+ return m_start_event;
+ }
+
+ inline interval_type const& interval() const
+ {
+ return m_interval;
+ }
+
+ inline time_type time() const
+ {
+ return (m_start_event)
+ ? interval().template get<0>()
+ : interval().template get<1>();
+ }
+
+ inline bool operator<(sweep_event const& other) const
+ {
+ if (! math::equals(time(), other.time()))
+ {
+ return time() < other.time();
+ }
+ // a start-event is before an end-event with the same event time
+ return is_start_event() && ! other.is_start_event();
+ }
+
+private:
+ boost::reference_wrapper<Interval const> m_interval;
+ bool m_start_event;
+};
+
+template <typename Event>
+struct event_greater
+{
+ inline bool operator()(Event const& event1, Event const& event2) const
+ {
+ return event2 < event1;
+ }
+};
+
+
+struct initialization_visitor
+{
+ template <typename Range, typename PriorityQueue, typename EventVisitor>
+ static inline void apply(Range const& range,
+ PriorityQueue& queue,
+ EventVisitor&)
+ {
+ BOOST_GEOMETRY_ASSERT(queue.empty());
+
+ // it is faster to build the queue directly from the entire
+ // range, rather than insert elements one after the other
+ PriorityQueue pq(boost::begin(range), boost::end(range));
+ std::swap(pq, queue);
+ }
+};
+
+
+template <typename Event>
+class event_visitor
+{
+ typedef typename Event::time_type event_time_type;
+ typedef typename Event::interval_type::difference_type difference_type;
+
+ typedef typename boost::remove_const
+ <
+ typename boost::remove_reference
+ <
+ event_time_type
+ >::type
+ >::type bare_time_type;
+
+
+public:
+ event_visitor()
+ : m_overlap_count(0)
+ , m_max_gap_left(0)
+ , m_max_gap_right(0)
+ {}
+
+ template <typename PriorityQueue>
+ inline void apply(Event const& event, PriorityQueue& queue)
+ {
+ if (event.is_start_event())
+ {
+ ++m_overlap_count;
+ queue.push(Event(event.interval(), false));
+ }
+ else
+ {
+ --m_overlap_count;
+ if (m_overlap_count == 0 && ! queue.empty())
+ {
+ // we may have a gap
+ BOOST_GEOMETRY_ASSERT(queue.top().is_start_event());
+
+ event_time_type next_event_time
+ = queue.top().interval().template get<0>();
+ difference_type gap = next_event_time - event.time();
+ if (gap > max_gap())
+ {
+ m_max_gap_left = event.time();
+ m_max_gap_right = next_event_time;
+ }
+ }
+ }
+ }
+
+ bare_time_type const& max_gap_left() const
+ {
+ return m_max_gap_left;
+ }
+
+ bare_time_type const& max_gap_right() const
+ {
+ return m_max_gap_right;
+ }
+
+ difference_type max_gap() const
+ {
+ return m_max_gap_right - m_max_gap_left;
+ }
+
+private:
+ std::size_t m_overlap_count;
+ bare_time_type m_max_gap_left, m_max_gap_right;
+};
+
+}} // namespace detail::max_interval_gap
+#endif // DOXYGEN_NO_DETAIL
+
+
+// Given a range of intervals I1, I2, ..., In, maximum_gap() returns
+// the maximum length of an interval M that satisfies the following
+// properties:
+//
+// 1. M.left >= min(I1, I2, ..., In)
+// 2. M.right <= max(I1, I2, ..., In)
+// 3. intersection(interior(M), Ik) is the empty set for all k=1, ..., n
+// 4. length(M) is maximal
+//
+// where M.left and M.right denote the left and right extreme values
+// for the interval M, and length(M) is equal to M.right - M.left.
+//
+// If M does not exist (or, alternatively, M is identified as the
+// empty set), 0 is returned.
+//
+// The algorithm proceeds for performing a sweep: the left endpoints
+// are inserted into a min-priority queue with the priority being the
+// value of the endpoint. The sweep algorithm maintains an "overlap
+// counter" that counts the number of overlaping intervals at any
+// specific sweep-time value.
+// There are two types of events encountered during the sweep:
+// (a) a start event: the left endpoint of an interval is found.
+// In this case the overlap count is increased by one and the
+// right endpoint of the interval in inserted into the event queue
+// (b) an end event: the right endpoint of an interval is found.
+// In this case the overlap count is decreased by one. If the
+// updated overlap count is 0, then we could expect to have a gap
+// in-between intervals. This gap is measured as the (absolute)
+// distance of the current interval right endpoint (being
+// processed) to the upcoming left endpoint of the next interval
+// to be processed (if such an interval exists). If the measured
+// gap is greater than the current maximum gap, it is recorded.
+// The initial maximum gap is initialized to 0. This value is returned
+// if no gap is found during the sweeping procedure.
+
+template <typename RangeOfIntervals, typename T>
+inline typename boost::range_value<RangeOfIntervals>::type::difference_type
+maximum_gap(RangeOfIntervals const& range_of_intervals,
+ T& max_gap_left, T& max_gap_right)
+{
+ typedef typename boost::range_value<RangeOfIntervals>::type interval_type;
+ typedef detail::max_interval_gap::sweep_event<interval_type> event_type;
+
+ // create a min-priority queue for the events
+ std::priority_queue
+ <
+ event_type,
+ std::vector<event_type>,
+ detail::max_interval_gap::event_greater<event_type>
+ > queue;
+
+ // define initialization and event-process visitors
+ detail::max_interval_gap::initialization_visitor init_visitor;
+ detail::max_interval_gap::event_visitor<event_type> sweep_visitor;
+
+ // perform the sweep
+ geometry::sweep(range_of_intervals,
+ queue,
+ init_visitor,
+ sweep_visitor);
+
+ max_gap_left = sweep_visitor.max_gap_left();
+ max_gap_right = sweep_visitor.max_gap_right();
+ return sweep_visitor.max_gap();
+}
+
+template <typename RangeOfIntervals>
+inline typename boost::range_value<RangeOfIntervals>::type::difference_type
+maximum_gap(RangeOfIntervals const& range_of_intervals)
+{
+ typedef typename boost::remove_const
+ <
+ typename boost::remove_reference
+ <
+ typename boost::range_value
+ <
+ RangeOfIntervals
+ >::type::value_type
+ >::type
+ >::type value_type;
+
+ value_type left, right;
+
+ return maximum_gap(range_of_intervals, left, right);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_MAX_INTERVAL_GAP_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/normalize.hpp b/3party/boost/boost/geometry/algorithms/detail/normalize.hpp
new file mode 100644
index 0000000000..913fe324b7
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/normalize.hpp
@@ -0,0 +1,294 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
+#include <boost/geometry/util/normalize_spheroidal_box_coordinates.hpp>
+
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace normalization
+{
+
+
+struct do_nothing
+{
+ template <typename GeometryIn, typename GeometryOut>
+ static inline void apply(GeometryIn const&, GeometryOut&)
+ {
+ }
+};
+
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct assign_loop
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const& longitude,
+ CoordinateType const& latitude,
+ PointIn const& point_in,
+ PointOut& point_out)
+ {
+ geometry::set<Dimension>(point_out, boost::numeric_cast
+ <
+ typename coordinate_type<PointOut>::type
+ >(geometry::get<Dimension>(point_in)));
+
+ assign_loop
+ <
+ Dimension + 1, DimensionCount
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+template <std::size_t DimensionCount>
+struct assign_loop<DimensionCount, DimensionCount>
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const&,
+ CoordinateType const&,
+ PointIn const&,
+ PointOut&)
+ {
+ }
+};
+
+template <std::size_t DimensionCount>
+struct assign_loop<0, DimensionCount>
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const& longitude,
+ CoordinateType const& latitude,
+ PointIn const& point_in,
+ PointOut& point_out)
+ {
+ geometry::set<0>(point_out, boost::numeric_cast
+ <
+ typename coordinate_type<PointOut>::type
+ >(longitude));
+
+ assign_loop
+ <
+ 1, DimensionCount
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+template <std::size_t DimensionCount>
+struct assign_loop<1, DimensionCount>
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const& longitude,
+ CoordinateType const& latitude,
+ PointIn const& point_in,
+ PointOut& point_out)
+ {
+ geometry::set<1>(point_out, boost::numeric_cast
+ <
+ typename coordinate_type<PointOut>::type
+ >(latitude));
+
+ assign_loop
+ <
+ 2, DimensionCount
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+
+template <typename PointIn, typename PointOut>
+struct normalize_point
+{
+ static inline void apply(PointIn const& point_in, PointOut& point_out)
+ {
+ typedef typename coordinate_type<PointIn>::type in_coordinate_type;
+
+ in_coordinate_type longitude = geometry::get<0>(point_in);
+ in_coordinate_type latitude = geometry::get<1>(point_in);
+
+ math::normalize_spheroidal_coordinates
+ <
+ typename coordinate_system<PointIn>::type::units,
+ in_coordinate_type
+ >(longitude, latitude);
+
+ assign_loop
+ <
+ 0, dimension<PointIn>::value
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+
+template <typename BoxIn, typename BoxOut>
+class normalize_box
+{
+ template <typename UnitsIn, typename UnitsOut, typename CoordinateInType>
+ static inline void apply_to_coordinates(CoordinateInType& lon_min,
+ CoordinateInType& lat_min,
+ CoordinateInType& lon_max,
+ CoordinateInType& lat_max,
+ BoxIn const& box_in,
+ BoxOut& box_out)
+ {
+ detail::indexed_point_view<BoxOut, min_corner> p_min_out(box_out);
+ assign_loop
+ <
+ 0, dimension<BoxIn>::value
+ >::apply(lon_min,
+ lat_min,
+ detail::indexed_point_view
+ <
+ BoxIn const, min_corner
+ >(box_in),
+ p_min_out);
+
+ detail::indexed_point_view<BoxOut, max_corner> p_max_out(box_out);
+ assign_loop
+ <
+ 0, dimension<BoxIn>::value
+ >::apply(lon_max,
+ lat_max,
+ detail::indexed_point_view
+ <
+ BoxIn const, max_corner
+ >(box_in),
+ p_max_out);
+ }
+
+public:
+ static inline void apply(BoxIn const& box_in, BoxOut& box_out)
+ {
+ typedef typename coordinate_type<BoxIn>::type in_coordinate_type;
+
+ in_coordinate_type lon_min = geometry::get<min_corner, 0>(box_in);
+ in_coordinate_type lat_min = geometry::get<min_corner, 1>(box_in);
+ in_coordinate_type lon_max = geometry::get<max_corner, 0>(box_in);
+ in_coordinate_type lat_max = geometry::get<max_corner, 1>(box_in);
+
+ math::normalize_spheroidal_box_coordinates
+ <
+ typename coordinate_system<BoxIn>::type::units,
+ in_coordinate_type
+ >(lon_min, lat_min, lon_max, lat_max);
+
+ apply_to_coordinates
+ <
+ typename coordinate_system<BoxIn>::type::units,
+ typename coordinate_system<BoxOut>::type::units
+ >(lon_min, lat_min, lon_max, lat_max, box_in, box_out);
+ }
+};
+
+
+}} // namespace detail::normalization
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryIn,
+ typename GeometryOut,
+ typename TagIn = typename tag<GeometryIn>::type,
+ typename TagOut = typename tag<GeometryOut>::type,
+ typename CSTagIn = typename cs_tag<GeometryIn>::type,
+ typename CSTagOut = typename cs_tag<GeometryOut>::type
+>
+struct normalize : detail::normalization::do_nothing
+{};
+
+
+template <typename PointIn, typename PointOut>
+struct normalize
+ <
+ PointIn, PointOut, point_tag, point_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::normalization::normalize_point<PointIn, PointOut>
+{};
+
+
+template <typename PointIn, typename PointOut>
+struct normalize
+ <
+ PointIn, PointOut, point_tag, point_tag, geographic_tag, geographic_tag
+ > : detail::normalization::normalize_point<PointIn, PointOut>
+{};
+
+
+template <typename BoxIn, typename BoxOut>
+struct normalize
+ <
+ BoxIn, BoxOut, box_tag, box_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::normalization::normalize_box<BoxIn, BoxOut>
+{};
+
+
+template <typename BoxIn, typename BoxOut>
+struct normalize
+ <
+ BoxIn, BoxOut, box_tag, box_tag, geographic_tag, geographic_tag
+ > : detail::normalization::normalize_box<BoxIn, BoxOut>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename GeometryIn, typename GeometryOut>
+inline void normalize(GeometryIn const& geometry_in, GeometryOut& geometry_out)
+{
+ dispatch::normalize
+ <
+ GeometryIn, GeometryOut
+ >::apply(geometry_in, geometry_out);
+}
+
+template <typename GeometryOut, typename GeometryIn>
+inline GeometryOut return_normalized(GeometryIn const& geometry_in)
+{
+ GeometryOut geometry_out;
+ detail::normalize(geometry_in, geometry_out);
+ return geometry_out;
+}
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/not.hpp b/3party/boost/boost/geometry/algorithms/detail/not.hpp
index abc3a4e168..43e71e2e37 100644
--- a/3party/boost/boost/geometry/algorithms/detail/not.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/not.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -32,10 +37,12 @@ namespace detail
\param geometry2 \param_geometry
\return Negation of the result of the policy
*/
-template <typename Geometry1, typename Geometry2, typename Policy>
+template <typename Policy>
struct not_
{
- static inline bool apply(Geometry1 const &geometry1, Geometry2 const& geometry2)
+ template <typename Geometry1, typename Geometry2>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2)
{
return ! Policy::apply(geometry1, geometry2);
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/occupation_info.hpp b/3party/boost/boost/geometry/algorithms/detail/occupation_info.hpp
index 92c07006f2..be995e5854 100644
--- a/3party/boost/boost/geometry/algorithms/detail/occupation_info.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/occupation_info.hpp
@@ -12,6 +12,7 @@
#include <algorithm>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
@@ -38,6 +39,7 @@ struct angle_info
segment_identifier seg_id;
int turn_index;
int operation_index;
+ std::size_t cluster_index;
Point intersection_point;
Point point; // either incoming or outgoing point
bool incoming;
@@ -55,16 +57,9 @@ class occupation_info
{
public :
typedef std::vector<AngleInfo> collection_type;
- typedef std::vector
- <
- detail::left_turns::turn_angle_info<typename AngleInfo::point_type>
- > turn_vector_type;
- collection_type angles; // each turn splitted in incoming/outgoing vectors
- turn_vector_type turns;
int count;
-
inline occupation_info()
: count(0)
{}
@@ -95,45 +90,47 @@ public :
{
info.point = incoming_point;
info.incoming = true;
- angles.push_back(info);
+ m_angles.push_back(info);
}
{
info.point = outgoing_point;
info.incoming = false;
- angles.push_back(info);
+ m_angles.push_back(info);
}
- detail::left_turns::turn_angle_info<typename AngleInfo::point_type> turn(seg_id, incoming_point, outgoing_point);
- turn.turn_index = turn_index;
- turns.push_back(turn);
}
- template <typename RobustPoint>
- inline void get_left_turns(RobustPoint const& origin,
- std::vector<detail::left_turns::left_turn>& turns_to_keep)
+ template <typename RobustPoint, typename Turns>
+ inline void get_left_turns(RobustPoint const& origin, Turns& turns)
{
// Sort on angle
- std::sort(angles.begin(), angles.end(),
+ std::sort(m_angles.begin(), m_angles.end(),
detail::left_turns::angle_less<typename AngleInfo::point_type>(origin));
+ // Group same-angled elements
+ std::size_t cluster_size = detail::left_turns::assign_cluster_indices(m_angles, origin);
// Block all turns on the right side of any turn
- detail::left_turns::block_turns_on_right_sides(turns, angles);
-
- detail::left_turns::get_left_turns(angles, origin, turns_to_keep);
+ detail::left_turns::block_turns(m_angles, cluster_size);
+ detail::left_turns::get_left_turns(m_angles, turns);
}
+#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
template <typename RobustPoint>
inline bool has_rounding_issues(RobustPoint const& origin) const
{
return detail::left_turns::has_rounding_issues(angles, origin);
}
+#endif
+
+private :
+ collection_type m_angles; // each turn splitted in incoming/outgoing vectors
};
template<typename Pieces>
inline void move_index(Pieces const& pieces, int& index, int& piece_index, int direction)
{
- BOOST_ASSERT(direction == 1 || direction == -1);
- BOOST_ASSERT(piece_index >= 0 && piece_index < static_cast<int>(boost::size(pieces)) );
- BOOST_ASSERT(index >= 0 && index < static_cast<int>(boost::size(pieces[piece_index].robust_ring)));
+ BOOST_GEOMETRY_ASSERT(direction == 1 || direction == -1);
+ BOOST_GEOMETRY_ASSERT(piece_index >= 0 && piece_index < static_cast<int>(boost::size(pieces)) );
+ BOOST_GEOMETRY_ASSERT(index >= 0 && index < static_cast<int>(boost::size(pieces[piece_index].robust_ring)));
index += direction;
if (direction == -1 && index < 0)
@@ -169,7 +166,6 @@ inline void add_incoming_and_outgoing_angles(
RobustPoint const& intersection_point, // rescaled
Turn const& turn,
Pieces const& pieces, // using rescaled offsets of it
- int turn_index,
int operation_index,
segment_identifier seg_id,
Info& info)
@@ -191,7 +187,7 @@ inline void add_incoming_and_outgoing_angles(
}
info.add(direction_points[0], direction_points[1], intersection_point,
- turn_index, operation_index, real_seg_id);
+ turn.turn_index, operation_index, real_seg_id);
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/add_rings.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/add_rings.hpp
index 5ff0b57d6e..fcb240941f 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/add_rings.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/add_rings.hpp
@@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
+#include <boost/range.hpp>
+
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp
index d44db17ad3..285edfdd6c 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp
@@ -20,6 +20,7 @@
#include <boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
@@ -42,7 +43,7 @@ inline bool points_equal_or_close(Point1 const& point1,
return true;
}
- if (! RobustPolicy::enabled)
+ if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled))
{
return false;
}
@@ -127,7 +128,7 @@ inline void clean_closing_dups_and_spikes(Range& range,
iterator_type first = boost::begin(range);
iterator_type second = first + 1;
iterator_type ultimate = boost::end(range) - 1;
- if (closed)
+ if (BOOST_GEOMETRY_CONDITION(closed))
{
ultimate--;
}
@@ -137,7 +138,7 @@ inline void clean_closing_dups_and_spikes(Range& range,
if (point_is_spike_or_equal(*second, *ultimate, *first, robust_policy))
{
range::erase(range, first);
- if (closed)
+ if (BOOST_GEOMETRY_CONDITION(closed))
{
// Remove closing last point
range::resize(range, boost::size(range) - 1);
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
index a7cbd038d2..047eb4993e 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
@@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
+#include <boost/range.hpp>
+
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/expand.hpp>
@@ -18,11 +20,6 @@
#include <boost/geometry/geometries/box.hpp>
-#ifdef BOOST_GEOMETRY_TIME_OVERLAY
-# include <boost/timer.hpp>
-#endif
-
-
namespace boost { namespace geometry
{
@@ -127,30 +124,30 @@ struct assign_visitor
template <typename Item>
inline void apply(Item const& outer, Item const& inner, bool first = true)
{
- if (first && outer.real_area < 0)
+ if (first && outer.abs_area < inner.abs_area)
{
- // Reverse arguments
+ // Apply with reversed arguments
apply(inner, outer, false);
return;
}
- if (math::larger(outer.real_area, 0))
+ if (m_check_for_orientation
+ || (math::larger(outer.real_area, 0)
+ && math::smaller(inner.real_area, 0)))
{
- if (inner.real_area < 0 || m_check_for_orientation)
- {
- ring_info_type& inner_in_map = m_ring_map[inner.id];
+ 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)
- )
+ if (geometry::within(inner_in_map.point, outer.envelope)
+ && within_selected_input(inner_in_map, outer.id, m_geometry1, m_geometry2, m_collection)
+ )
+ {
+ // Assign a parent if there was no earlier parent, or the newly
+ // found parent is smaller than the previous one
+ if (inner_in_map.parent.source_index == -1
+ || outer.abs_area < inner_in_map.parent_area)
{
- // 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;
- }
+ inner_in_map.parent = outer.id;
+ inner_in_map.parent_area = outer.abs_area;
}
}
}
@@ -186,11 +183,6 @@ inline void assign_parents(Geometry1 const& geometry1,
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
@@ -226,10 +218,6 @@ inline void assign_parents(Geometry1 const& geometry1,
}
}
-#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)
@@ -272,11 +260,6 @@ inline void assign_parents(Geometry1 const& geometry1,
<
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)
@@ -288,13 +271,21 @@ inline void assign_parents(Geometry1 const& geometry1,
{
it->second.discarded = true;
}
- else if (it->second.parent.source_index >= 0 && it->second.get_area() > 0)
+ else if (it->second.parent.source_index >= 0
+ && math::larger(it->second.get_area(), 0))
{
- // Discard positive inner ring with parent
- it->second.discarded = true;
+ const ring_info_type& parent = ring_map[it->second.parent];
+
+ if (math::larger(parent.area, 0))
+ {
+ // Discard positive inner ring with positive parent
+ it->second.discarded = true;
+ }
+ // Remove parent ID from any positive inner ring
it->second.parent.source_index = -1;
}
- else if (it->second.parent.source_index < 0 && it->second.get_area() < 0)
+ else if (it->second.parent.source_index < 0
+ && math::smaller(it->second.get_area(), 0))
{
// Reverse negative ring without parent
it->second.reversed = true;
@@ -313,6 +304,8 @@ inline void assign_parents(Geometry1 const& geometry1,
}
}
+
+// Version for one geometry (called by buffer)
template
<
typename Geometry,
@@ -324,7 +317,7 @@ inline void assign_parents(Geometry const& geometry,
RingMap& ring_map,
bool check_for_orientation)
{
- // Call it with an empty geometry
+ // Call it with an empty geometry as second geometry (source_id == 1)
// (ring_map should be empty for source_id==1)
Geometry empty;
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/check_enrich.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
index 03be18e07a..25e442982b 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
@@ -12,12 +12,8 @@
#include <cstddef>
-
-#include <boost/assert.hpp>
#include <boost/range.hpp>
-
-
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
index fc4f657322..b1a25c9f5e 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -160,10 +165,12 @@ template
typename OutputLinestring,
typename OutputIterator,
typename Range,
+ typename RobustPolicy,
typename Box,
typename Strategy
>
OutputIterator clip_range_with_box(Box const& b, Range const& range,
+ RobustPolicy const&,
OutputIterator out, Strategy const& strategy)
{
if (boost::begin(range) == boost::end(range))
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
index 4040fbe6b1..f294cbcca2 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
@@ -14,14 +14,15 @@
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.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/tags.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>
+#include <boost/geometry/util/range.hpp>
+#include <boost/geometry/views/detail/normalized_view.hpp>
namespace boost { namespace geometry
@@ -36,41 +37,24 @@ 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;
+ detail::normalized_view<Range const> view(range);
+
+ signed_index_type const n = boost::size(view);
+ signed_index_type index = seg_id.segment_index;
if (second)
{
index++;
- if (index >= int(boost::size(range)))
+ if (index >= n)
{
index = 0;
}
}
- // Exception?
- if (index >= int(boost::size(range)))
- {
- return false;
- }
-
- cview_type cview(range);
- rview_type view(cview);
-
+ BOOST_GEOMETRY_ASSERT(index >= 0 && index < n);
geometry::convert(*(boost::begin(view) + index), point);
return true;
@@ -95,8 +79,8 @@ struct copy_segment_point_polygon
>::apply
(
seg_id.ring_index < 0
- ? geometry::exterior_ring(polygon)
- : geometry::interior_rings(polygon)[seg_id.ring_index],
+ ? geometry::exterior_ring(polygon)
+ : range::at(geometry::interior_rings(polygon), seg_id.ring_index),
seg_id, second,
point
);
@@ -111,7 +95,7 @@ struct copy_segment_point_box
SegmentIdentifier const& seg_id, bool second,
PointOut& point)
{
- int index = seg_id.segment_index;
+ signed_index_type index = seg_id.segment_index;
if (second)
{
index++;
@@ -139,14 +123,14 @@ struct copy_segment_point_multi
PointOut& point)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_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);
+ return Policy::apply(range::at(multi, seg_id.multi_index), seg_id, second, point);
}
};
@@ -322,6 +306,8 @@ inline bool copy_segment_point(Geometry1 const& geometry1, Geometry2 const& geom
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
+ BOOST_GEOMETRY_ASSERT(seg_id.source_index == 0 || seg_id.source_index == 1);
+
if (seg_id.source_index == 0)
{
return dispatch::copy_segment_point
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
index d4bf0a90f4..98393af1b4 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
@@ -6,6 +6,7 @@
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -18,14 +19,11 @@
#include <vector>
#include <boost/array.hpp>
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/integral_constant.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/ring_type.hpp>
@@ -39,6 +37,8 @@
#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
#include <boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp>
+#include <boost/geometry/util/range.hpp>
+
namespace boost { namespace geometry
{
@@ -60,7 +60,8 @@ struct copy_segments_ring
typename RangeOut
>
static inline void apply(Ring const& ring,
- SegmentIdentifier const& seg_id, int to_index,
+ SegmentIdentifier const& seg_id,
+ signed_index_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
@@ -89,10 +90,10 @@ struct copy_segments_ring
// So we use the ever-circling iterator and determine when to step out
- int const from_index = seg_id.segment_index + 1;
+ signed_index_type const from_index = seg_id.segment_index + 1;
// Sanity check
- BOOST_ASSERT(from_index < int(boost::size(view)));
+ BOOST_GEOMETRY_ASSERT(from_index < static_cast<signed_index_type>(boost::size(view)));
ec_iterator it(boost::begin(view), boost::end(view),
boost::begin(view) + from_index);
@@ -100,12 +101,12 @@ struct copy_segments_ring
// [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
+ signed_index_type const count = from_index <= to_index
? to_index - from_index + 1
- : int(boost::size(view)) - from_index + to_index + 1;
+ : static_cast<signed_index_type>(boost::size(view))
+ - from_index + to_index + 1;
- for (size_type i = 0; i < count; ++i, ++it)
+ for (signed_index_type i = 0; i < count; ++i, ++it)
{
detail::overlay::append_no_dups_or_spikes(current_output, *it, robust_policy);
}
@@ -146,27 +147,27 @@ public:
typename RangeOut
>
static inline void apply(LineString const& ls,
- SegmentIdentifier const& seg_id, int to_index,
+ SegmentIdentifier const& seg_id,
+ signed_index_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
- int const from_index = seg_id.segment_index + 1;
+ signed_index_type const from_index = seg_id.segment_index + 1;
// Sanity check
if ( from_index > to_index
|| from_index < 0
- || to_index >= int(boost::size(ls)) )
+ || to_index >= static_cast<signed_index_type>(boost::size(ls)) )
{
return;
}
- typedef typename boost::range_difference<LineString>::type size_type;
- size_type const count = to_index - from_index + 1;
+ signed_index_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)
+ for (signed_index_type i = 0; i < count; ++i, ++it)
{
append_to_output(current_output, *it, robust_policy,
boost::integral_constant<bool, RemoveSpikes>());
@@ -185,7 +186,8 @@ struct copy_segments_polygon
typename RangeOut
>
static inline void apply(Polygon const& polygon,
- SegmentIdentifier const& seg_id, int to_index,
+ SegmentIdentifier const& seg_id,
+ signed_index_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
@@ -193,8 +195,8 @@ struct copy_segments_polygon
copy_segments_ring<Reverse>::apply
(
seg_id.ring_index < 0
- ? geometry::exterior_ring(polygon)
- : geometry::interior_rings(polygon)[seg_id.ring_index],
+ ? geometry::exterior_ring(polygon)
+ : range::at(geometry::interior_rings(polygon), seg_id.ring_index),
seg_id, to_index,
robust_policy,
current_output
@@ -214,14 +216,15 @@ struct copy_segments_box
typename RangeOut
>
static inline void apply(Box const& box,
- SegmentIdentifier const& seg_id, int to_index,
+ SegmentIdentifier const& seg_id,
+ signed_index_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
- int index = seg_id.segment_index + 1;
- BOOST_ASSERT(index < 5);
+ signed_index_type index = seg_id.segment_index + 1;
+ BOOST_GEOMETRY_ASSERT(index < 5);
- int const count = index <= to_index
+ signed_index_type const count = index <= to_index
? to_index - index + 1
: 5 - index + to_index + 1;
@@ -232,7 +235,7 @@ struct copy_segments_box
// (possibly cyclic) copy to output
// (see comments in ring-version)
- for (int i = 0; i < count; i++, index++)
+ for (signed_index_type i = 0; i < count; i++, index++)
{
detail::overlay::append_no_dups_or_spikes(current_output,
bp[index % 5], robust_policy);
@@ -253,22 +256,23 @@ struct copy_segments_multi
typename RangeOut
>
static inline void apply(MultiGeometry const& multi_geometry,
- SegmentIdentifier const& seg_id, int to_index,
+ SegmentIdentifier const& seg_id,
+ signed_index_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_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,
- robust_policy,
- current_output);
+ Policy::apply(range::at(multi_geometry, seg_id.multi_index),
+ seg_id, to_index,
+ robust_policy,
+ current_output);
}
};
@@ -340,7 +344,8 @@ template
typename RangeOut
>
inline void copy_segments(Geometry const& geometry,
- SegmentIdentifier const& seg_id, int to_index,
+ SegmentIdentifier const& seg_id,
+ signed_index_type to_index,
RobustPolicy const& robust_policy,
RangeOut& range_out)
{
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
index 9f4dd218de..3d65449551 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
@@ -22,14 +22,13 @@
# 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>
#include <boost/geometry/policies/robustness/robust_type.hpp>
+#include <boost/geometry/strategies/side.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
# include <boost/geometry/algorithms/detail/overlay/check_enrich.hpp>
#endif
@@ -48,17 +47,23 @@ struct indexed_turn_operation
{
typedef TurnOperation type;
- int index;
- int operation_index;
+ std::size_t turn_index;
+ std::size_t operation_index;
bool discarded;
- TurnOperation subject;
-
- inline indexed_turn_operation(int i, int oi, TurnOperation const& s)
- : index(i)
+ // use pointers to avoid copies, const& is not possible because of usage in vector
+ segment_identifier const* other_seg_id; // segment id of other segment of intersection of two segments
+ TurnOperation const* subject;
+
+ inline indexed_turn_operation(std::size_t ti, std::size_t oi,
+ TurnOperation const& sub,
+ segment_identifier const& oid)
+ : turn_index(ti)
, operation_index(oi)
, discarded(false)
- , subject(s)
+ , other_seg_id(&oid)
+ , subject(boost::addressof(sub))
{}
+
};
template <typename IndexedTurnOperation>
@@ -107,51 +112,53 @@ private :
mutable bool* m_clustered;
typedef typename geometry::point_type<Geometry1>::type point_type;
- typedef typename geometry::robust_point_type
- <
- point_type,
- RobustPolicy
- >::type robust_point_type;
-
- // TODO: this function is shared with handle_tangencies
- // The one in handle_tangencies will go as soon as we have
- // reliable "cluster_info" (using occupation_map, get_left_turns)
- inline void get_situation_map(Indexed const& left, Indexed const& right,
- robust_point_type& pi_rob, robust_point_type& pj_rob,
- robust_point_type& ri_rob, robust_point_type& rj_rob,
- robust_point_type& si_rob, robust_point_type& sj_rob) const
+
+ inline bool default_order(Indexed const& left, Indexed const& right) const
+ {
+ // We've nothing to sort on. Take the indexes
+ return left.turn_index < right.turn_index;
+ }
+
+ inline bool consider_relative_order(Indexed const& left,
+ Indexed const& right) const
{
point_type pi, pj, ri, rj, si, sj;
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
- left.subject.seg_id,
+ left.subject->seg_id,
pi, pj);
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
- left.subject.other_id,
+ *left.other_seg_id,
ri, rj);
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
- right.subject.other_id,
+ *right.other_seg_id,
si, sj);
- geometry::recalculate(pi_rob, pi, m_robust_policy);
- geometry::recalculate(pj_rob, pj, m_robust_policy);
- geometry::recalculate(ri_rob, ri, m_robust_policy);
- geometry::recalculate(rj_rob, rj, m_robust_policy);
- geometry::recalculate(si_rob, si, m_robust_policy);
- geometry::recalculate(sj_rob, sj, m_robust_policy);
- }
-
- inline bool consider_relative_order(Indexed const& left,
- Indexed const& right) const
- {
- robust_point_type pi, pj, ri, rj, si, sj;
- get_situation_map(left, right, pi, pj, ri, rj, si, sj);
- int const order = get_relative_order
+ typedef typename strategy::side::services::default_strategy
<
- robust_point_type
- >::apply(pi, pj, ri, rj, si, sj);
- //debug("r/o", order == -1);
- return order == -1;
+ typename cs_tag<point_type>::type
+ >::type strategy;
+
+ int const side_rj_p = strategy::apply(pi, pj, rj);
+ int const side_sj_p = strategy::apply(pi, pj, sj);
+
+ // Put the one turning left (1; right == -1) as last
+ if (side_rj_p != side_sj_p)
+ {
+ return side_rj_p < side_sj_p;
+ }
+
+ int const side_sj_r = strategy::apply(ri, rj, sj);
+ int const side_rj_s = strategy::apply(si, sj, rj);
+
+ // If they both turn left: the most left as last
+ // If they both turn right: this is not relevant, but take also here most left
+ if (side_rj_s != side_sj_r)
+ {
+ return side_rj_s < side_sj_r;
+ }
+
+ return default_order(left, right);
}
public :
@@ -160,33 +167,32 @@ public :
// 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 (! (left.subject->seg_id == right.subject->seg_id))
+ {
+ return left.subject->seg_id < right.subject->seg_id;
+ }
- if (sl == sr)
+ // Both left and right are located on the SAME segment.
+
+ if (! (left.subject->fraction == right.subject->fraction))
{
- // Both left and right are located on the SAME segment.
- if (left.subject.fraction == right.subject.fraction)
- {
- // First check "real" intersection (crosses)
- // -> distance zero due to precision, solve it by sorting
- // TODO: reconsider this. Using integer maths, this will
- // ALWAYS return 0 because either fractions are different, or
- // the (currently calculated) relative-order is identical
- if (m_turn_points[left.index].method == method_crosses
- && m_turn_points[right.index].method == method_crosses)
- {
- return consider_relative_order(left, right);
- }
+ return left.subject->fraction < right.subject->fraction;
+ }
- // If that is not the case, cluster it later on.
- // Indicate that this is necessary.
- *m_clustered = true;
- }
+
+ // First check "real" intersection (crosses)
+ // -> distance zero due to precision, solve it by sorting
+ if (m_turn_points[left.turn_index].method == method_crosses
+ && m_turn_points[right.turn_index].method == method_crosses)
+ {
+ return consider_relative_order(left, right);
}
- return sl == sr
- ? left.subject.fraction < right.subject.fraction
- : sl < sr;
+
+ // If that is not the case, cluster it later on.
+ // Indicate that this is necessary.
+ *m_clustered = true;
+
+ return default_order(left, right);
}
};
@@ -200,13 +206,13 @@ inline void update_discarded(Turns& turn_points, Operations& operations)
it != boost::end(operations);
++it)
{
- if (turn_points[it->index].discarded)
+ if (turn_points[it->turn_index].discarded)
{
it->discarded = true;
}
else if (it->discarded)
{
- turn_points[it->index].discarded = true;
+ turn_points[it->turn_index].discarded = true;
}
}
}
@@ -262,14 +268,14 @@ inline void enrich_sort(Container& operations,
it != boost::end(operations);
prev = it++)
{
- operations_type& prev_op = turn_points[prev->index]
+ operations_type& prev_op = turn_points[prev->turn_index]
.operations[prev->operation_index];
- operations_type& op = turn_points[it->index]
+ operations_type& op = turn_points[it->turn_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)
+ && (turn_points[prev->turn_index].method != method_crosses
+ || turn_points[it->turn_index].method != method_crosses)
&& prev_op.fraction == op.fraction)
{
if (begin_cluster == boost::end(operations))
@@ -346,19 +352,19 @@ inline void enrich_assign(Container& operations,
prev = it++)
{
operations_type& prev_op
- = turn_points[prev->index].operations[prev->operation_index];
+ = turn_points[prev->turn_index].operations[prev->operation_index];
operations_type& op
- = turn_points[it->index].operations[it->operation_index];
+ = turn_points[it->turn_index].operations[it->operation_index];
prev_op.enriched.travels_to_ip_index
- = it->index;
+ = static_cast<int>(it->turn_index);
prev_op.enriched.travels_to_vertex_index
- = it->subject.seg_id.segment_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;
+ prev_op.enriched.next_ip_index = static_cast<int>(it->turn_index);
}
first = false;
}
@@ -371,16 +377,16 @@ inline void enrich_assign(Container& operations,
it != boost::end(operations);
++it)
{
- operations_type& op = turn_points[it->index]
+ operations_type& op = turn_points[it->turn_index]
.operations[it->operation_index];
- std::cout << it->index
- << " meth: " << method_char(turn_points[it->index].method)
+ std::cout << it->turn_index
+ << " meth: " << method_char(turn_points[it->turn_index].method)
<< " seg: " << op.seg_id
<< " dst: " << op.fraction // needs define
- << " 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")
+ << " op: " << operation_char(turn_points[it->turn_index].operations[0].operation)
+ << operation_char(turn_points[it->turn_index].operations[1].operation)
+ << " dsc: " << (turn_points[it->turn_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
@@ -401,7 +407,7 @@ inline void create_map(TurnPoints const& turn_points, MappedVector& mapped_vecto
typedef typename boost::range_value<TurnPoints>::type turn_point_type;
typedef typename turn_point_type::container_type container_type;
- int index = 0;
+ std::size_t index = 0;
for (typename boost::range_iterator<TurnPoints const>::type
it = boost::begin(turn_points);
it != boost::end(turn_points);
@@ -410,7 +416,7 @@ inline void create_map(TurnPoints const& turn_points, MappedVector& mapped_vecto
// Add operations on this ring, but skip discarded ones
if (! it->discarded)
{
- int op_index = 0;
+ std::size_t op_index = 0;
for (typename boost::range_iterator<container_type const>::type
op_it = boost::begin(it->operations);
op_it != boost::end(it->operations);
@@ -428,7 +434,8 @@ inline void create_map(TurnPoints const& turn_points, MappedVector& mapped_vecto
);
mapped_vector[ring_id].push_back
(
- IndexedType(index, op_index, *op_it)
+ IndexedType(index, op_index, *op_it,
+ it->operations[1 - op_index].seg_id)
);
}
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
index 6668c99249..ef32edeefa 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
@@ -37,7 +37,7 @@ struct enrichment_info
// 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;
+ signed_index_type travels_to_vertex_index;
// same but now IP index, so "next IP index" but not on THIS segment
int travels_to_ip_index;
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/follow.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/follow.hpp
index 632f79f40e..acf38d09ab 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/follow.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/follow.hpp
@@ -163,7 +163,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
static inline void enter(LineStringOut& current_piece,
LineString const& ,
segment_identifier& segment_id,
- int , Point const& point,
+ signed_index_type , Point const& point,
Operation const& operation,
RobustPolicy const& ,
OutputIterator& )
@@ -186,7 +186,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
static inline void leave(LineStringOut& current_piece,
LineString const& linestring,
segment_identifier& segment_id,
- int index, Point const& point,
+ signed_index_type index, Point const& point,
Operation const& ,
RobustPolicy const& robust_policy,
OutputIterator& out)
@@ -217,7 +217,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
static inline void isolated_point(LineStringOut&,
LineString const&,
segment_identifier&,
- int, Point const& point,
+ signed_index_type, Point const& point,
Operation const& , OutputIterator& out)
{
LineStringOut isolated_point_ls;
@@ -268,7 +268,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
static inline void enter(LineStringOut& current_piece,
LineString const& linestring,
segment_identifier& segment_id,
- int index, Point const& point,
+ signed_index_type index, Point const& point,
Operation const& operation,
RobustPolicy const& robust_policy,
OutputIterator& out)
@@ -289,7 +289,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
static inline void leave(LineStringOut& current_piece,
LineString const& linestring,
segment_identifier& segment_id,
- int index, Point const& point,
+ signed_index_type index, Point const& point,
Operation const& operation,
RobustPolicy const& robust_policy,
OutputIterator& out)
@@ -309,7 +309,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
static inline void isolated_point(LineStringOut&,
LineString const&,
segment_identifier&,
- int, Point const&,
+ signed_index_type, Point const&,
Operation const&, OutputIterator&)
{
}
@@ -494,8 +494,10 @@ public :
detail::copy_segments::copy_segments_linestring
<
false, RemoveSpikes
- >::apply(linestring, current_segment_id,
- boost::size(linestring) - 1, robust_policy,
+ >::apply(linestring,
+ current_segment_id,
+ static_cast<signed_index_type>(boost::size(linestring) - 1),
+ robust_policy,
current_piece);
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
index 851162bda8..a3ebb58d86 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
@@ -14,9 +14,9 @@
#include <algorithm>
#include <iterator>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -35,6 +35,23 @@
namespace boost { namespace geometry
{
+#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
+class inconsistent_turns_exception : public geometry::exception
+{
+public:
+
+ inline inconsistent_turns_exception() {}
+
+ virtual ~inconsistent_turns_exception() throw()
+ {}
+
+ virtual char const* what() const throw()
+ {
+ return "Boost.Geometry Inconsistent Turns exception";
+ }
+};
+#endif
+
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace overlay
@@ -125,7 +142,7 @@ static inline bool is_isolated_point(Turn const& turn,
if ( turn.method == method_none )
{
- BOOST_ASSERT( operation.operation == operation_continue );
+ BOOST_GEOMETRY_ASSERT( operation.operation == operation_continue );
return true;
}
@@ -263,8 +280,10 @@ protected:
detail::copy_segments::copy_segments_linestring
<
false, false // do not reverse; do not remove spikes
- >::apply(linestring, current_segment_id,
- boost::size(linestring) - 1, robust_policy,
+ >::apply(linestring,
+ current_segment_id,
+ static_cast<signed_index_type>(boost::size(linestring) - 1),
+ robust_policy,
current_piece);
}
@@ -302,7 +321,14 @@ public:
oit);
}
- BOOST_ASSERT( enter_count == 0 );
+#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
+ if (enter_count != 0)
+ {
+ throw inconsistent_turns_exception();
+ }
+#else
+ BOOST_GEOMETRY_ASSERT(enter_count == 0);
+#endif
return process_end(entered, linestring,
current_segment_id, current_piece,
@@ -378,7 +404,7 @@ protected:
};
template <typename TurnIterator>
- static inline int get_multi_index(TurnIterator it)
+ static inline signed_index_type get_multi_index(TurnIterator it)
{
return boost::begin(it->operations)->seg_id.multi_index;
}
@@ -386,10 +412,10 @@ protected:
class has_other_multi_id
{
private:
- int m_multi_id;
+ signed_index_type m_multi_id;
public:
- has_other_multi_id(int multi_id)
+ has_other_multi_id(signed_index_type multi_id)
: m_multi_id(multi_id) {}
template <typename Turn>
@@ -407,7 +433,7 @@ public:
TurnIterator first, TurnIterator beyond,
OutputIterator oit)
{
- BOOST_ASSERT( first != beyond );
+ BOOST_GEOMETRY_ASSERT( first != beyond );
typedef copy_linestrings_in_range
<
@@ -420,7 +446,7 @@ public:
// Iterate through all intersection points (they are
// ordered along the each linestring)
- int current_multi_id = get_multi_index(first);
+ signed_index_type current_multi_id = get_multi_index(first);
oit = copy_linestrings::apply(ls_first,
ls_first + current_multi_id,
@@ -437,7 +463,7 @@ public:
oit = Base::apply(*(ls_first + current_multi_id),
linear, per_ls_current, per_ls_next, oit);
- int next_multi_id(-1);
+ signed_index_type next_multi_id(-1);
linestring_iterator ls_next = ls_beyond;
if ( per_ls_next != beyond )
{
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
index 63011c7d48..4668189924 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
@@ -12,6 +12,9 @@
#include <cstddef>
+#include <boost/mpl/if.hpp>
+#include <boost/range.hpp>
+
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/get_ring.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/get_ring.hpp
index ab9219a3d5..460c30def3 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/get_ring.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/get_ring.hpp
@@ -10,15 +10,16 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.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/tags.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -34,16 +35,16 @@ template<typename Tag>
struct get_ring
{};
-// A container of rings (multi-ring but that does not exist)
+// A range 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)
+ template<typename Range>
+ static inline typename boost::range_value<Range>::type const&
+ apply(ring_identifier const& id, Range const& container)
{
- return container[id.multi_index];
+ return range::at(container, id.multi_index);
}
};
@@ -81,14 +82,14 @@ struct get_ring<polygon_tag>
ring_identifier const& id,
Polygon const& polygon)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_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];
+ : range::at(interior_rings(polygon), id.ring_index);
}
};
@@ -101,13 +102,13 @@ struct get_ring<multi_polygon_tag>
ring_identifier const& id,
MultiPolygon const& multi_polygon)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_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]);
+ range::at(multi_polygon, id.multi_index));
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
index 5b3a74de5a..717f0b47a9 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -10,8 +15,10 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
-#include <boost/assert.hpp>
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/algorithms/convert.hpp>
@@ -104,17 +111,19 @@ struct base_turn_handler
template <typename TurnInfo, typename IntersectionInfo>
static inline void assign_point(TurnInfo& ti,
method_type method,
- IntersectionInfo const& info, int index)
+ IntersectionInfo const& info, unsigned int index)
{
ti.method = method;
- BOOST_ASSERT(index >= 0 && unsigned(index) < info.count); // TODO remove this
+
+ BOOST_GEOMETRY_ASSERT(index < info.count);
+
geometry::convert(info.intersections[index], ti.point);
ti.operations[0].fraction = info.fractions[index].robust_ra;
ti.operations[1].fraction = info.fractions[index].robust_rb;
}
template <typename IntersectionInfo>
- static inline int non_opposite_to_index(IntersectionInfo const& info)
+ static inline unsigned int non_opposite_to_index(IntersectionInfo const& info)
{
return info.fractions[0].robust_rb < info.fractions[1].robust_rb
? 1 : 0;
@@ -132,7 +141,7 @@ struct touch_interior : public base_turn_handler
// Index: 0, P is the interior, Q is touching and vice versa
template
<
- int Index,
+ unsigned int Index,
typename Point1,
typename Point2,
typename IntersectionInfo,
@@ -155,8 +164,9 @@ struct touch_interior : public base_turn_handler
// 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;
+ BOOST_STATIC_ASSERT(Index <= 1);
+ static unsigned int const index_p = Index;
+ static unsigned int const index_q = 1 - Index;
int const side_qi_p = dir_info.sides.template get<index_q, 0>();
int const side_qk_p = side.qk_wrt_p1();
@@ -166,7 +176,7 @@ struct touch_interior : public base_turn_handler
// 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;
+ unsigned int index = side_qk_p == -1 ? index_p : index_q;
ti.operations[index].operation = operation_union;
ti.operations[1 - index].operation = operation_intersection;
return;
@@ -193,7 +203,7 @@ struct touch_interior : public base_turn_handler
// 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;
+ unsigned int index = side_qk_q == 1 ? index_q : index_p;
ti.operations[index].operation = operation_union;
ti.operations[1 - index].operation = operation_intersection;
}
@@ -215,10 +225,10 @@ struct touch_interior : public base_turn_handler
// 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
+ ti.operations[index_p].operation = side_qk_q == 1
? operation_intersection
: operation_union;
- ti.operations[1 - Index].operation = operation_blocked;
+ ti.operations[index_q].operation = operation_blocked;
}
}
else
@@ -503,27 +513,25 @@ struct equal_opposite : public base_turn_handler
typename Point1,
typename Point2,
typename OutputIterator,
- typename IntersectionInfo,
- typename DirInfo
+ typename IntersectionInfo
>
static inline void apply(Point1 const& pi, Point2 const& qi,
/* by value: */ TurnInfo tp,
OutputIterator& out,
- IntersectionInfo const& intersection_info,
- DirInfo const& dir_info)
+ IntersectionInfo const& intersection_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++)
+ for (unsigned int i = 0; i < 2; i++)
{
tp.operations[i].operation = operation_opposite;
}
- for (unsigned int i = 0; i < intersection_info.count; i++)
+ for (unsigned int i = 0; i < intersection_info.i_info().count; i++)
{
- assign_point(tp, method_none, intersection_info, i);
- AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
+ assign_point(tp, method_none, intersection_info.i_info(), i);
+ AssignPolicy::apply(tp, pi, qi, intersection_info);
*out++ = tp;
}
}
@@ -589,7 +597,7 @@ struct collinear : public base_turn_handler
int const arrival = dir_info.arrival[0];
// Should not be 0, this is checked before
- BOOST_ASSERT(arrival != 0);
+ BOOST_GEOMETRY_ASSERT(arrival != 0);
int const side_p = side.pk_wrt_p1();
int const side_q = side.qk_wrt_q1();
@@ -653,17 +661,19 @@ private :
template
<
- int Index,
- typename Point,
+ unsigned int Index,
+ typename Point1,
+ typename Point2,
typename IntersectionInfo
>
- static inline bool set_tp(Point const& , Point const& , Point const& , int side_rk_r,
+ static inline bool set_tp(Point1 const& , Point1 const& , Point1 const& , int side_rk_r,
bool const handle_robustness,
- Point const& , Point const& , int side_rk_s,
+ Point2 const& , Point2 const& , int side_rk_s,
TurnInfo& tp, IntersectionInfo const& intersection_info)
{
- boost::ignore_unused_variable_warning(handle_robustness);
- boost::ignore_unused_variable_warning(side_rk_s);
+ BOOST_STATIC_ASSERT(Index <= 1);
+
+ boost::ignore_unused(handle_robustness, side_rk_s);
operation_type blocked = operation_blocked;
switch(side_rk_r)
@@ -714,7 +724,6 @@ public:
typename Point2,
typename OutputIterator,
typename IntersectionInfo,
- typename DirInfo,
typename SidePolicy
>
static inline void apply(
@@ -726,10 +735,9 @@ public:
OutputIterator& out,
IntersectionInfo const& intersection_info,
- DirInfo const& dir_info,
SidePolicy const& side)
{
- apply(pi, pj, pk, qi, qj, qk, tp_model, out, intersection_info, dir_info, side, empty_transformer);
+ apply(pi, pj, pk, qi, qj, qk, tp_model, out, intersection_info, side, empty_transformer);
}
public:
@@ -739,7 +747,6 @@ public:
typename Point2,
typename OutputIterator,
typename IntersectionInfo,
- typename DirInfo,
typename SidePolicy,
typename TurnTransformer
>
@@ -751,50 +758,52 @@ public:
TurnInfo const& tp_model,
OutputIterator& out,
- IntersectionInfo const& intersection_info,
- DirInfo const& dir_info,
+ IntersectionInfo const& info,
SidePolicy const& side,
TurnTransformer turn_transformer,
bool const is_pk_valid = true, bool const is_qk_valid = true)
{
TurnInfo tp = tp_model;
+ int const p_arrival = info.d_info().arrival[0];
+ int const q_arrival = info.d_info().arrival[1];
+
// If P arrives within Q, there is a turn dependent on P
- if ( dir_info.arrival[0] == 1
+ if ( p_arrival == 1
&& is_pk_valid
- && set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, intersection_info) )
+ && set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, info.i_info()) )
{
turn_transformer(tp);
- AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
+ AssignPolicy::apply(tp, pi, qi, info);
*out++ = tp;
}
// If Q arrives within P, there is a turn dependent on Q
- if ( dir_info.arrival[1] == 1
+ if ( q_arrival == 1
&& is_qk_valid
- && set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, intersection_info) )
+ && set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, info.i_info()) )
{
turn_transformer(tp);
- AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
+ AssignPolicy::apply(tp, pi, qi, 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))
+ if ((q_arrival == -1 && p_arrival == 0)
+ || (p_arrival == -1 && q_arrival == 0))
{
- for (int i = 0; i < 2; i++)
+ for (unsigned int i = 0; i < 2; i++)
{
tp.operations[i].operation = operation_opposite;
}
- for (unsigned int i = 0; i < intersection_info.count; i++)
+ for (unsigned int i = 0; i < info.i_info().count; i++)
{
- assign_point(tp, method_collinear, intersection_info, i);
- AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
+ assign_point(tp, method_collinear, info.i_info(), i);
+ AssignPolicy::apply(tp, pi, qi, info);
*out++ = tp;
}
}
@@ -832,7 +841,7 @@ struct crosses : public base_turn_handler
// 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;
+ unsigned int const index = side_qi_p1 == 1 ? 0 : 1;
ti.operations[index].operation = operation_union;
ti.operations[1 - index].operation = operation_intersection;
}
@@ -866,10 +875,9 @@ struct assign_null_policy
typename Info,
typename Point1,
typename Point2,
- typename IntersectionInfo,
- typename DirInfo
+ typename IntersectionInfo
>
- static inline void apply(Info& , Point1 const& , Point2 const&, IntersectionInfo const&, DirInfo const&)
+ static inline void apply(Info& , Point1 const& , Point2 const&, IntersectionInfo const&)
{}
};
@@ -932,7 +940,7 @@ struct get_turn_info
&& inters.i_info().count > 0)
{
only_convert::apply(tp, inters.i_info());
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
break;
@@ -967,7 +975,7 @@ struct get_turn_info
tp, inters.i_info(), inters.d_info(),
swapped_side_calc);
}
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
break;
@@ -975,7 +983,7 @@ struct get_turn_info
{
crosses<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
tp, inters.i_info(), inters.d_info());
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
break;
@@ -984,7 +992,7 @@ struct get_turn_info
// Both touch (both arrive there)
touch<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
tp, inters.i_info(), inters.d_info(), inters.sides());
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
break;
@@ -996,7 +1004,7 @@ struct get_turn_info
// or collinear-and-ending at intersection point
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
tp, inters.i_info(), inters.d_info(), inters.sides());
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
else
@@ -1006,7 +1014,7 @@ struct get_turn_info
TurnInfo,
AssignPolicy
>::apply(pi, qi,
- tp, out, inters.i_info(), inters.d_info());
+ tp, out, inters);
}
}
break;
@@ -1031,7 +1039,7 @@ struct get_turn_info
tp, inters.i_info(), inters.d_info(), inters.sides());
}
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
else
@@ -1041,7 +1049,7 @@ struct get_turn_info
TurnInfo,
AssignPolicy
>::apply(pi, pj, pk, qi, qj, qk,
- tp, out, inters.i_info(), inters.d_info(), inters.sides());
+ tp, out, inters, inters.sides());
}
}
break;
@@ -1051,7 +1059,7 @@ struct get_turn_info
if (AssignPolicy::include_degenerate)
{
only_convert::apply(tp, inters.i_info());
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
index 6cf4d25abb..0b3cb72747 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
@@ -14,6 +14,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
@@ -153,7 +154,7 @@ public:
}
else
{
- BOOST_ASSERT(result.template get<0>().count == 1);
+ BOOST_GEOMETRY_ASSERT(result.template get<0>().count == 1);
ips[0].p_operation = union_or_blocked_same_dirs(arrival_a, is_p_last);
ips[0].q_operation = union_or_blocked_same_dirs(arrival_b, is_q_last);
@@ -245,10 +246,6 @@ struct get_turn_info_for_endpoint
if ( ip_count == 0 )
return false;
- int segment_index0 = tp_model.operations[0].seg_id.segment_index;
- int segment_index1 = tp_model.operations[1].seg_id.segment_index;
- BOOST_ASSERT(segment_index0 >= 0 && segment_index1 >= 0);
-
if ( !is_p_first && !is_p_last && !is_q_first && !is_q_last )
return false;
@@ -294,17 +291,17 @@ struct get_turn_info_for_endpoint
linear_intersections::ip_info const& ip_info,
TurnInfo const& tp_model,
IntersectionInfo const& inters,
- int ip_index,
+ unsigned int ip_index,
OutputIterator out)
{
#ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS_LINEAR_LINEAR
// may this give false positives for INTs?
typename IntersectionResult::point_type const&
inters_pt = result.template get<0>().intersections[ip_index];
- BOOST_ASSERT(ip_info.is_pi == equals::equals_point_point(pi, inters_pt));
- BOOST_ASSERT(ip_info.is_qi == equals::equals_point_point(qi, inters_pt));
- BOOST_ASSERT(ip_info.is_pj == equals::equals_point_point(pj, inters_pt));
- BOOST_ASSERT(ip_info.is_qj == equals::equals_point_point(qj, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_pi == equals::equals_point_point(pi, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_qi == equals::equals_point_point(qi, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_pj == equals::equals_point_point(pj, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_qj == equals::equals_point_point(qj, inters_pt));
#endif
// TODO - calculate first/last only if needed
@@ -400,7 +397,7 @@ struct get_turn_info_for_endpoint
RobustPoint2 const& ri2, RobustPoint2 const& rj2, RobustPoint2 const& rk2,
bool first1, bool last1, bool first2, bool last2,
bool ip_i2, bool ip_j2, TurnInfo const& tp_model,
- IntersectionInfo const& inters, int ip_index,
+ IntersectionInfo const& inters, unsigned int ip_index,
operation_type & op1, operation_type & op2)
{
boost::ignore_unused_variable_warning(i2);
@@ -416,8 +413,8 @@ struct get_turn_info_for_endpoint
// may this give false positives for INTs?
typename IntersectionResult::point_type const&
inters_pt = inters.i_info().intersections[ip_index];
- BOOST_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
- BOOST_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
#endif
if ( ip_i2 )
{
@@ -452,7 +449,7 @@ struct get_turn_info_for_endpoint
}
else
{
- BOOST_ASSERT(operations_combination(operations, operation_intersection, operation_union));
+ BOOST_GEOMETRY_ASSERT(operations_combination(operations, operation_intersection, operation_union));
//op1 = operation_union;
//op2 = operation_union;
}
@@ -467,8 +464,8 @@ struct get_turn_info_for_endpoint
// may this give false positives for INTs?
typename IntersectionResult::point_type const&
inters_pt = inters.i_info().intersections[ip_index];
- BOOST_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
- BOOST_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
#endif
if ( ip_i2 )
{
@@ -503,7 +500,7 @@ struct get_turn_info_for_endpoint
}
else
{
- BOOST_ASSERT(operations_combination(operations, operation_intersection, operation_union));
+ BOOST_GEOMETRY_ASSERT(operations_combination(operations, operation_intersection, operation_union));
//op1 = operation_blocked;
//op2 = operation_union;
}
@@ -539,7 +536,7 @@ struct get_turn_info_for_endpoint
typename OutputIterator>
static inline void assign(Point1 const& pi, Point2 const& qi,
IntersectionResult const& result,
- int ip_index,
+ unsigned int ip_index,
method_type method,
operation_type op0, operation_type op1,
turn_position pos0, turn_position pos1,
@@ -564,7 +561,7 @@ struct get_turn_info_for_endpoint
// NOTE: is_collinear is NOT set for the first endpoint
// for which there is no preceding segment
- //BOOST_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
+ //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
if ( ! is_p_first_ip )
{
tp.operations[0].is_collinear = op0 != operation_intersection
@@ -589,7 +586,9 @@ struct get_turn_info_for_endpoint
}
}
- AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
+ // TODO: this should get an intersection_info, which is unavailable here
+ // Because the assign_null policy accepts any structure, we pass the result instead for now
+ AssignPolicy::apply(tp, pi, qi, result);
*out++ = tp;
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
index eead0d719b..e0d75108b9 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
index 20340a6080..ccb42d4c92 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
@@ -2,18 +2,22 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LA_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LA_HPP
+#include <boost/geometry/core/assert.hpp>
+
+#include <boost/geometry/util/condition.hpp>
+
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp>
@@ -28,6 +32,8 @@ namespace detail { namespace overlay {
template<typename AssignPolicy>
struct get_turn_info_linear_areal
{
+ // Currently only Linear spikes are handled
+ // Areal spikes are ignored
static const bool handle_spikes = true;
template
@@ -122,7 +128,7 @@ struct get_turn_info_linear_areal
calculate_spike_operation(tp.operations[0].operation,
inters, is_p_last);
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
@@ -135,7 +141,7 @@ struct get_turn_info_linear_areal
replace_operations_i(tp.operations[0].operation, tp.operations[1].operation);
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
break;
@@ -220,9 +226,9 @@ struct get_turn_info_linear_areal
inters, is_p_last);
// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
- if ( ! handle_spikes
+ if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|| ignore_spike
|| ! append_opposite_spikes<append_touches>( // for 'i' or 'c' i???
tp, inters, is_p_last, is_q_last, out) )
@@ -256,10 +262,10 @@ struct get_turn_info_linear_areal
transformer(tp);
// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
// conditionally handle spikes
- if ( ! handle_spikes
+ if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|| ! append_collinear_spikes(tp, inters, is_p_last, is_q_last,
method_touch, append_equal, out) )
{
@@ -273,7 +279,7 @@ struct get_turn_info_linear_areal
TurnInfo,
AssignPolicy
>::apply(pi, qi,
- tp, out, inters.i_info(), inters.d_info());
+ tp, out, inters);
}
}
}
@@ -319,10 +325,10 @@ struct get_turn_info_linear_areal
transformer(tp);
// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
// conditionally handle spikes
- if ( ! handle_spikes
+ if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|| ! append_collinear_spikes(tp, inters, is_p_last, is_q_last,
method_replace, version, out) )
{
@@ -336,7 +342,7 @@ struct get_turn_info_linear_areal
turn_transformer_ec<false> transformer(method_touch_interior);
// conditionally handle spikes
- if ( handle_spikes )
+ if ( BOOST_GEOMETRY_CONDITION(handle_spikes) )
{
append_opposite_spikes<append_collinear_opposite>(
tp, inters, is_p_last, is_q_last, out);
@@ -351,8 +357,9 @@ struct get_turn_info_linear_areal
TurnInfo,
AssignPolicy
>::apply(pi, pj, pk, qi, qj, qk,
- tp, out, inters.i_info(), inters.d_info(),
- inters.sides(), transformer);
+ tp, out, inters,
+ inters.sides(), transformer,
+ !is_p_last, true); // qk is always valid
}
}
}
@@ -360,7 +367,7 @@ struct get_turn_info_linear_areal
case '0' :
{
// degenerate points
- if (AssignPolicy::include_degenerate)
+ if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) )
{
only_convert::apply(tp, inters.i_info());
@@ -376,7 +383,7 @@ struct get_turn_info_linear_areal
}
// tp.operations[1].position = position_middle;
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
}
@@ -408,20 +415,37 @@ struct get_turn_info_linear_areal
if ( is_p_spike )
{
- bool going_in = false, going_out = false;
-
int const pk_q1 = inters.sides().pk_wrt_q1();
- int const pk_q2 = inters.sides().pk_wrt_q2();
+
+ bool going_in = pk_q1 < 0; // Pk on the right
+ bool going_out = pk_q1 > 0; // Pk on the left
+
+ int const qk_q1 = inters.sides().qk_wrt_q1();
- if ( inters.sides().qk_wrt_q1() <= 0 ) // Q turning R or C
+ // special cases
+ if ( qk_q1 < 0 ) // Q turning R
{
- going_in = pk_q1 < 0 && pk_q2 < 0; // Pk on the right of both
- going_out = pk_q1 > 0 || pk_q2 > 0; // Pk on the left of one of them
+ // spike on the edge point
+ // if it's already known that the spike is going out this musn't be checked
+ if ( ! going_out
+ && equals::equals_point_point(inters.rpj(), inters.rqj()) )
+ {
+ int const pk_q2 = inters.sides().pk_wrt_q2();
+ going_in = pk_q1 < 0 && pk_q2 < 0; // Pk on the right of both
+ going_out = pk_q1 > 0 || pk_q2 > 0; // Pk on the left of one of them
+ }
}
- else
+ else if ( qk_q1 > 0 ) // Q turning L
{
- going_in = pk_q1 < 0 || pk_q2 < 0; // Pk on the right of one of them
- going_out = pk_q1 > 0 && pk_q2 > 0; // Pk on the left of both
+ // spike on the edge point
+ // if it's already known that the spike is going in this musn't be checked
+ if ( ! going_in
+ && equals::equals_point_point(inters.rpj(), inters.rqj()) )
+ {
+ int const pk_q2 = inters.sides().pk_wrt_q2();
+ going_in = pk_q1 < 0 || pk_q2 < 0; // Pk on the right of one of them
+ going_out = pk_q1 > 0 && pk_q2 > 0; // Pk on the left of both
+ }
}
if ( going_in )
@@ -461,10 +485,16 @@ struct get_turn_info_linear_areal
&& inters.is_spike_p();
// TODO: throw an exception for spike in Areal?
- /*bool is_q_spike = tp.operations[1].operation == spike_op
- && ! is_q_last
- && inters.is_spike_q();*/
+ /*bool is_q_spike = tp.operations[1].operation == operation_continue
+ && inters.is_spike_q();
+ // both are collinear spikes on the same IP, we can just follow both
+ if ( is_p_spike && is_q_spike )
+ {
+ return false;
+ }
+ // spike on Linear - it's turning back on the boundary of Areal
+ else*/
if ( is_p_spike )
{
tp.method = method;
@@ -477,7 +507,18 @@ struct get_turn_info_linear_areal
return true;
}
-
+ // spike on Areal - Linear is going outside
+ /*else if ( is_q_spike )
+ {
+ tp.method = method;
+ tp.operations[0].operation = operation_union;
+ tp.operations[1].operation = operation_continue;
+ *out++ = tp;
+ *out++ = tp;
+
+ return true;
+ }*/
+
return false;
}
@@ -492,48 +533,71 @@ struct get_turn_info_linear_areal
bool is_p_last, bool /*is_q_last*/,
OutIt out)
{
- bool is_p_spike = ( Version == append_touches ?
+ static const bool is_version_touches = (Version == append_touches);
+
+ bool is_p_spike = ( is_version_touches ?
( tp.operations[0].operation == operation_continue
|| tp.operations[0].operation == operation_intersection ) : // i ???
true )
&& ! is_p_last
&& inters.is_spike_p();
+
// TODO: throw an exception for spike in Areal?
- /*bool is_q_spike = ( Version == append_touches ?
- ( tp.operations[1].operation == operation_continue
- || tp.operations[1].operation == operation_intersection ) :
- true )
- && ! is_q_last
- && inters.is_spike_q();*/
+ /*bool is_q_spike = ( ( Version == append_touches
+ && tp.operations[1].operation == operation_continue )
+ || ( Version == append_collinear_opposite
+ && tp.operations[1].operation == operation_none ) )
+ && inters.is_spike_q();
- if ( is_p_spike && ( Version == append_touches || inters.d_info().arrival[0] == 1 ) )
+ if ( is_p_spike && is_q_spike )
{
- if ( Version == append_touches )
- {
- tp.operations[0].is_collinear = true;
- //tp.operations[1].is_collinear = false;
- tp.method = method_touch;
- }
- else
+ // u/u or nothing?
+ return false;
+ }
+ else*/
+ if ( is_p_spike )
+ {
+ if ( BOOST_GEOMETRY_CONDITION(is_version_touches)
+ || inters.d_info().arrival[0] == 1 )
{
- tp.operations[0].is_collinear = true;
- //tp.operations[1].is_collinear = false;
-
- BOOST_ASSERT(inters.i_info().count > 1);
- base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1);
+ if ( BOOST_GEOMETRY_CONDITION(is_version_touches) )
+ {
+ tp.operations[0].is_collinear = true;
+ //tp.operations[1].is_collinear = false;
+ tp.method = method_touch;
+ }
+ else
+ {
+ tp.operations[0].is_collinear = true;
+ //tp.operations[1].is_collinear = false;
- AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters.i_info(), inters.d_info());
- }
+ BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1);
+ base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1);
- tp.operations[0].operation = operation_blocked;
+ AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters);
+ }
+
+ tp.operations[0].operation = operation_blocked;
+ tp.operations[1].operation = operation_continue; // boundary
+ *out++ = tp;
+ tp.operations[0].operation = operation_continue; // boundary
+ //tp.operations[1].operation = operation_continue; // boundary
+ *out++ = tp;
+
+ return true;
+ }
+ }
+ /*else if ( is_q_spike )
+ {
+ tp.operations[0].is_collinear = true;
+ tp.method = is_version_touches ? method_touch : method_touch_interior;
+ tp.operations[0].operation = operation_continue;
tp.operations[1].operation = operation_continue; // boundary
*out++ = tp;
- tp.operations[0].operation = operation_continue; // boundary
- //tp.operations[1].operation = operation_continue; // boundary
*out++ = tp;
return true;
- }
+ }*/
return false;
}
@@ -587,7 +651,7 @@ struct get_turn_info_linear_areal
operation_type & op1 = turn.operations[1].operation;
// NOTE: probably only if methods are WRT IPs, not segments!
- if ( IsFront
+ if ( BOOST_GEOMETRY_CONDITION(IsFront)
|| op0 == operation_intersection || op0 == operation_union
|| op1 == operation_intersection || op1 == operation_union )
{
@@ -652,10 +716,6 @@ struct get_turn_info_linear_areal
if ( ip_count == 0 )
return false;
- const int segment_index0 = tp_model.operations[0].seg_id.segment_index;
- const int segment_index1 = tp_model.operations[1].seg_id.segment_index;
- BOOST_ASSERT(segment_index0 >= 0 && segment_index1 >= 0);
-
if ( !is_p_first && !is_p_last )
return false;
@@ -670,7 +730,9 @@ struct get_turn_info_linear_areal
// ANALYSE AND ASSIGN FIRST
// IP on the first point of Linear Geometry
- if ( EnableFirst && is_p_first && ip0.is_pi && !ip0.is_qi ) // !q0i prevents duplication
+ bool was_first_point_handled = false;
+ if ( BOOST_GEOMETRY_CONDITION(EnableFirst)
+ && is_p_first && ip0.is_pi && !ip0.is_qi ) // !q0i prevents duplication
{
TurnInfo tp = tp_model;
tp.operations[0].position = position_front;
@@ -739,14 +801,16 @@ struct get_turn_info_linear_areal
// here is_p_first_ip == true
tp.operations[0].is_collinear = false;
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
+
+ was_first_point_handled = true;
}
// ANALYSE AND ASSIGN LAST
// IP on the last point of Linear Geometry
- if ( EnableLast
+ if ( BOOST_GEOMETRY_CONDITION(EnableLast)
&& is_p_last
&& ( ip_count > 1 ? (ip1.is_pj && !ip1.is_qi) : (ip0.is_pj && !ip0.is_qi) ) ) // prevents duplication
{
@@ -754,7 +818,7 @@ struct get_turn_info_linear_areal
if ( inters.i_info().count > 1 )
{
- //BOOST_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
+ //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
tp.operations[0].is_collinear = true;
tp.operations[1].operation = opposite ? operation_continue : operation_union;
}
@@ -787,13 +851,14 @@ struct get_turn_info_linear_areal
// equals<> or collinear<> will assign the second point,
// we'd like to assign the first one
- int ip_index = ip_count > 1 ? 1 : 0;
+ unsigned int ip_index = ip_count > 1 ? 1 : 0;
base_turn_handler::assign_point(tp, tp.method, inters.i_info(), ip_index);
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
- return true;
+ // don't ignore the first IP if the segment is opposite
+ return !( opposite && ip_count > 1 ) || was_first_point_handled;
}
// don't ignore anything for now
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
index 4f0384877f..19f0859cbb 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -14,9 +14,13 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp>
+#include <boost/geometry/util/condition.hpp>
+
namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
@@ -120,7 +124,7 @@ struct get_turn_info_linear_linear
tp.operations[0].operation,
tp.operations[1].operation);
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
}
@@ -132,7 +136,7 @@ struct get_turn_info_linear_linear
replace_operations_i(tp.operations[0].operation, tp.operations[1].operation);
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
break;
@@ -260,9 +264,9 @@ struct get_turn_info_linear_linear
tp.operations[1].operation);
// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
- if ( ! handle_spikes
+ if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|| ! append_opposite_spikes<append_touches>(tp, inters,
is_p_last, is_q_last,
out) )
@@ -293,18 +297,24 @@ struct get_turn_info_linear_linear
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
tp, inters.i_info(), inters.d_info(), inters.sides());
+ operation_type spike_op
+ = ( tp.operations[0].operation != operation_continue
+ || tp.operations[1].operation != operation_continue ) ?
+ operation_union :
+ operation_continue;
+
// transform turn
turn_transformer_ec transformer(method_touch);
transformer(tp);
// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
// conditionally handle spikes
- if ( ! handle_spikes
+ if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|| ! append_collinear_spikes(tp, inters,
is_p_last, is_q_last,
- method_touch, operation_union,
+ method_touch, spike_op,
out) )
{
*out++ = tp; // no spikes
@@ -318,7 +328,7 @@ struct get_turn_info_linear_linear
<
TurnInfo,
AssignPolicy
- >::apply(pi, qi, tp, out, inters.i_info(), inters.d_info());
+ >::apply(pi, qi, tp, out, inters);
}
}
}
@@ -351,7 +361,11 @@ struct get_turn_info_linear_linear
tp, inters.i_info(), inters.d_info(), inters.sides());
method_replace = method_touch;
- spike_op = operation_union;
+ if ( tp.operations[0].operation != operation_continue
+ || tp.operations[1].operation != operation_continue )
+ {
+ spike_op = operation_union;
+ }
}
else
{
@@ -367,10 +381,10 @@ struct get_turn_info_linear_linear
transformer(tp);
// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
// conditionally handle spikes
- if ( ! handle_spikes
+ if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|| ! append_collinear_spikes(tp, inters,
is_p_last, is_q_last,
method_replace, spike_op,
@@ -386,7 +400,7 @@ struct get_turn_info_linear_linear
turn_transformer_ec transformer(method_touch_interior);
// conditionally handle spikes
- if ( handle_spikes )
+ if ( BOOST_GEOMETRY_CONDITION(handle_spikes) )
{
append_opposite_spikes<append_collinear_opposite>(tp, inters,
is_p_last, is_q_last,
@@ -402,7 +416,7 @@ struct get_turn_info_linear_linear
TurnInfo,
AssignPolicy
>::apply(pi, pj, pk, qi, qj, qk,
- tp, out, inters.i_info(), inters.d_info(), inters.sides(),
+ tp, out, inters, inters.sides(),
transformer, !is_p_last, !is_q_last);
}
}
@@ -411,7 +425,7 @@ struct get_turn_info_linear_linear
case '0' :
{
// degenerate points
- if (AssignPolicy::include_degenerate)
+ if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) )
{
only_convert::apply(tp, inters.i_info());
@@ -437,7 +451,7 @@ struct get_turn_info_linear_linear
tp.operations[1].position = position_back;
}
- AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
}
@@ -478,6 +492,14 @@ struct get_turn_info_linear_linear
if ( is_p_spike && is_q_spike )
{
+ if ( tp.method == method_equal
+ && tp.operations[0].operation == operation_continue
+ && tp.operations[1].operation == operation_continue )
+ {
+ // treat both non-opposite collinear spikes as no-spikes
+ return false;
+ }
+
tp.method = method;
tp.operations[0].operation = operation_blocked;
tp.operations[1].operation = operation_blocked;
@@ -527,13 +549,15 @@ struct get_turn_info_linear_linear
bool is_p_last, bool is_q_last,
OutIt out)
{
- bool is_p_spike = ( Version == append_touches ?
+ static const bool is_version_touches = (Version == append_touches);
+
+ bool is_p_spike = ( is_version_touches ?
( tp.operations[0].operation == operation_continue
|| tp.operations[0].operation == operation_intersection ) :
true )
&& ! is_p_last
&& inters.is_spike_p();
- bool is_q_spike = ( Version == append_touches ?
+ bool is_q_spike = ( is_version_touches ?
( tp.operations[1].operation == operation_continue
|| tp.operations[1].operation == operation_intersection ) :
true )
@@ -542,9 +566,11 @@ struct get_turn_info_linear_linear
bool res = false;
- if ( is_p_spike && ( Version == append_touches || inters.d_info().arrival[0] == 1 ) )
+ if ( is_p_spike
+ && ( BOOST_GEOMETRY_CONDITION(is_version_touches)
+ || inters.d_info().arrival[0] == 1 ) )
{
- if ( Version == append_touches )
+ if ( BOOST_GEOMETRY_CONDITION(is_version_touches) )
{
tp.operations[0].is_collinear = true;
tp.operations[1].is_collinear = false;
@@ -555,13 +581,12 @@ struct get_turn_info_linear_linear
tp.operations[0].is_collinear = true;
tp.operations[1].is_collinear = false;
- BOOST_ASSERT(inters.i_info().count > 1);
+ BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1);
base_turn_handler::assign_point(tp, method_touch_interior,
inters.i_info(), 1);
- AssignPolicy::apply(tp, inters.pi(), inters.qi(),
- inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters);
}
tp.operations[0].operation = operation_blocked;
@@ -574,9 +599,11 @@ struct get_turn_info_linear_linear
res = true;
}
- if ( is_q_spike && ( Version == append_touches || inters.d_info().arrival[1] == 1 ) )
+ if ( is_q_spike
+ && ( BOOST_GEOMETRY_CONDITION(is_version_touches)
+ || inters.d_info().arrival[1] == 1 ) )
{
- if ( Version == append_touches )
+ if ( BOOST_GEOMETRY_CONDITION(is_version_touches) )
{
tp.operations[0].is_collinear = false;
tp.operations[1].is_collinear = true;
@@ -587,12 +614,11 @@ struct get_turn_info_linear_linear
tp.operations[0].is_collinear = false;
tp.operations[1].is_collinear = true;
- BOOST_ASSERT(inters.i_info().count > 0);
+ BOOST_GEOMETRY_ASSERT(inters.i_info().count > 0);
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 0);
- AssignPolicy::apply(tp, inters.pi(), inters.qi(),
- inters.i_info(), inters.d_info());
+ AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters);
}
tp.operations[0].operation = operation_intersection;
@@ -662,7 +688,7 @@ struct get_turn_info_linear_linear
operation_type & op0 = turn.operations[0].operation;
operation_type & op1 = turn.operations[1].operation;
- BOOST_ASSERT(op0 != operation_blocked || op1 != operation_blocked );
+ BOOST_GEOMETRY_ASSERT(op0 != operation_blocked || op1 != operation_blocked );
if ( op0 == operation_blocked )
{
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turns.hpp
index 513bfd372f..eac799b114 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/get_turns.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/get_turns.hpp
@@ -22,6 +22,7 @@
#include <boost/array.hpp>
#include <boost/concept_check.hpp>
#include <boost/mpl/if.hpp>
+#include <boost/mpl/vector_c.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
@@ -54,6 +55,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/recalculate.hpp>
+#include <boost/geometry/algorithms/detail/sections/section_box_policies.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp>
@@ -62,8 +64,7 @@
#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
-
-#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/detail/sections/section_functions.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
# include <sstream>
@@ -229,7 +230,7 @@ public :
// section 2: [--------------]
// section 1: |----|---|---|---|---|
for (prev1 = it1++, next1++;
- it1 != end1 && ! exceeding<0>(dir1, *prev1, sec2.bounding_box, robust_policy);
+ it1 != end1 && ! detail::section::exceeding<0>(dir1, *prev1, sec2.bounding_box, robust_policy);
++prev1, ++it1, ++index1, ++next1, ++ndi1)
{
ever_circling_iterator<range1_iterator> nd_next1(
@@ -247,7 +248,7 @@ public :
next2++;
for (prev2 = it2++, next2++;
- it2 != end2 && ! exceeding<0>(dir2, *prev2, sec1.bounding_box, robust_policy);
+ it2 != end2 && ! detail::section::exceeding<0>(dir2, *prev2, sec1.bounding_box, robust_policy);
++prev2, ++it2, ++index2, ++next2, ++ndi2)
{
bool skip = same_source;
@@ -278,13 +279,12 @@ public :
typedef typename boost::range_value<Turns>::type turn_info;
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;
+ 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);
std::size_t const size_before = boost::size(turns);
@@ -300,8 +300,8 @@ public :
if (InterruptPolicy::enabled)
{
if (interrupt_policy.apply(
- std::make_pair(boost::begin(turns) + size_before,
- boost::end(turns))))
+ std::make_pair(range::pos(turns, size_before),
+ boost::end(turns))))
{
return false;
}
@@ -319,25 +319,6 @@ private :
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, typename RobustPolicy>
- static inline bool preceding(int dir, Point const& point, Box const& box, RobustPolicy const& robust_policy)
- {
- typename robust_point_type<Point, RobustPolicy>::type robust_point;
- geometry::recalculate(robust_point, point, robust_policy);
- return (dir == 1 && get<Dim>(robust_point) < get<min_corner, Dim>(box))
- || (dir == -1 && get<Dim>(robust_point) > get<max_corner, Dim>(box));
- }
-
- template <size_t Dim, typename Point, typename Box, typename RobustPolicy>
- static inline bool exceeding(int dir, Point const& point, Box const& box, RobustPolicy const& robust_policy)
- {
- typename robust_point_type<Point, RobustPolicy>::type robust_point;
- geometry::recalculate(robust_point, point, robust_policy);
- return (dir == 1 && get<Dim>(robust_point) > get<max_corner, Dim>(box))
- || (dir == -1 && get<Dim>(robust_point) < get<min_corner, Dim>(box));
- }
-
template <typename Iterator, typename RangeIterator, typename Section, typename RobustPolicy>
static inline void advance_to_non_duplicate_next(Iterator& next,
RangeIterator const& it, Section const& section, RobustPolicy const& robust_policy)
@@ -388,7 +369,7 @@ private :
// Mimic section-iterator:
// Skip to point such that section interects other box
prev = it++;
- for(; it != end && preceding<0>(dir, *it, other_bounding_box, robust_policy);
+ for(; it != end && detail::section::preceding<0>(dir, *it, other_bounding_box, robust_policy);
prev = it++, index++, ndi++)
{}
// Go back one step because we want to start completely preceding
@@ -396,24 +377,6 @@ private :
}
};
-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,
@@ -497,12 +460,15 @@ public:
point_type, RobustPolicy
>::type
> box_type;
- typedef typename geometry::sections<box_type, 2> sections_type;
+ typedef geometry::sections<box_type, 2> sections_type;
sections_type sec1, sec2;
+ typedef boost::mpl::vector_c<std::size_t, 0, 1> dimensions;
- geometry::sectionalize<Reverse1>(geometry1, robust_policy, true, sec1, 0);
- geometry::sectionalize<Reverse2>(geometry2, robust_policy, true, sec2, 1);
+ geometry::sectionalize<Reverse1, dimensions>(geometry1, robust_policy,
+ sec1, 0);
+ geometry::sectionalize<Reverse2, dimensions>(geometry2, robust_policy,
+ sec2, 1);
// ... and then partition them, intersecting overlapping sections in visitor method
section_visitor
@@ -514,7 +480,9 @@ public:
geometry::partition
<
- box_type, get_section_box, ovelaps_section_box
+ box_type,
+ detail::section::get_section_box,
+ detail::section::overlaps_section_box
>::apply(sec1, sec2, visitor);
}
};
@@ -557,7 +525,8 @@ struct get_turns_cs
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy,
- int multi_index = -1, int ring_index = -1)
+ signed_index_type multi_index = -1,
+ signed_index_type ring_index = -1)
{
if ( boost::size(range) <= 1)
{
@@ -570,7 +539,8 @@ struct get_turns_cs
cview_type cview(range);
view_type view(cview);
- typename boost::range_size<view_type>::type segments_count1 = boost::size(view) - 1;
+ typedef typename boost::range_size<view_type>::type size_type;
+ size_type segments_count1 = boost::size(view) - 1;
iterator_type it = boost::begin(view);
@@ -583,7 +553,7 @@ struct get_turns_cs
//char previous_side[2] = {0, 0};
- int index = 0;
+ signed_index_type index = 0;
for (iterator_type prev = it++;
it != boost::end(view);
@@ -622,7 +592,7 @@ struct get_turns_cs
bp[0], bp[1], bp[2], bp[3],
// NOTE: some dummy values could be passed below since this would be called only for Polygons and Boxes
index == 0,
- unsigned(index) == segments_count1,
+ size_type(index) == segments_count1,
robust_policy,
turns, interrupt_policy);
// Future performance enhancement:
@@ -678,8 +648,6 @@ private:
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,
@@ -729,7 +697,7 @@ struct get_turns_polygon_cs
int source_id2, Box const& box,
RobustPolicy const& robust_policy,
Turns& turns, InterruptPolicy& interrupt_policy,
- int multi_index = -1)
+ signed_index_type multi_index = -1)
{
typedef typename geometry::ring_type<Polygon>::type ring_type;
@@ -747,7 +715,7 @@ struct get_turns_polygon_cs
turns, interrupt_policy,
multi_index, -1);
- int i = 0;
+ signed_index_type i = 0;
typename interior_return_type<Polygon const>::type
rings = interior_rings(polygon);
@@ -786,7 +754,7 @@ struct get_turns_multi_polygon_cs
Multi const
>::type iterator_type;
- int i = 0;
+ signed_index_type i = 0;
for (iterator_type it = boost::begin(multi);
it != boost::end(multi);
++it, ++i)
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp
index 9bb8284985..277a223d47 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp
@@ -28,6 +28,11 @@
#include <boost/geometry/geometries/segment.hpp>
+// TODO: the approach below should be completely replaced by the new
+// get_left_turns, to keep the outgoing vector which has open space one of its
+// sides.
+
+
namespace boost { namespace geometry
{
@@ -76,9 +81,14 @@ private :
RobustPolicy
>::type robust_point_type;
- // TODO: this function is shared with enrich_intersection_points
- // Still called by #case_102_multi, #case_107_multi
- // #case_recursive_boxes_3
+ inline bool default_order(Indexed const& left, Indexed const& right) const
+ {
+ // We've nothing to sort on. Take the indexes
+ return left.turn_index < right.turn_index;
+ }
+
+ // Still necessary in some situations,
+ // for example #case_102_multi, #case_107_multi, #case_recursive_boxes_3
inline void get_situation_map(Indexed const& left, Indexed const& right,
robust_point_type& pi_rob, robust_point_type& pj_rob,
robust_point_type& ri_rob, robust_point_type& rj_rob,
@@ -87,13 +97,13 @@ private :
point_type pi, pj, ri, rj, si, sj;
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
- left.subject.seg_id,
+ left.subject->seg_id,
pi, pj);
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
- left.subject.other_id,
+ *left.other_seg_id,
ri, rj);
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
- right.subject.other_id,
+ *right.other_seg_id,
si, sj);
geometry::recalculate(pi_rob, pi, m_rescale_policy);
@@ -167,7 +177,7 @@ private :
{
if (skip) return;
- std::cout << "Case: " << header << " for " << left.index << " / " << right.index << std::endl;
+ std::cout << "Case: " << header << " for " << left.turn_index << " / " << right.turn_index << std::endl;
robust_point_type pi, pj, ri, rj, si, sj;
get_situation_map(left, right, pi, pj, ri, rj, si, sj);
@@ -196,15 +206,15 @@ private :
std::cout << header
//<< " order: " << order
- << " ops: " << operation_char(left.subject.operation)
- << "/" << operation_char(right.subject.operation)
+ << " 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
#if BOOST_GEOMETRY_HANDLE_TANGENCIES_WITH_OVERLAP_INFO
<< " cnts: " << int(prc) << "," << int(psc) << "," << int(rsc)
#endif
- //<< " idx: " << left.index << "/" << right.index
+ //<< " idx: " << left.turn_index << "/" << right.turn_index
;
if (! extra.empty())
@@ -229,17 +239,17 @@ private :
, std::string const& // header
) const
{
- bool ret = left.index < right.index;
+ bool ret = left.turn_index < right.turn_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)
+ 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)
+ else if (left.subject->operation == operation_blocked
+ && right.subject->operation == operation_union)
{
ret = false;
}
@@ -263,26 +273,26 @@ private :
{
bool ret = false;
- if (left.subject.operation == operation_union
- && right.subject.operation == operation_union)
+ 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)
+ 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)
+ else if (right.subject->operation == operation_union
+ && left.subject->operation == operation_blocked)
{
ret = false;
}
- else if (left.subject.operation == operation_union)
+ else if (left.subject->operation == operation_union)
{
ret = true;
}
- else if (right.subject.operation == operation_union)
+ else if (right.subject->operation == operation_union)
{
ret = false;
}
@@ -307,10 +317,10 @@ private :
{
//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
+ 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;
}
@@ -319,13 +329,13 @@ private :
) const
{
// Take first intersection, then blocked.
- if (left.subject.operation == operation_intersection
- && right.subject.operation == operation_blocked)
+ if (left.subject->operation == operation_intersection
+ && right.subject->operation == operation_blocked)
{
return true;
}
- else if (left.subject.operation == operation_blocked
- && right.subject.operation == operation_intersection)
+ else if (left.subject->operation == operation_blocked
+ && right.subject->operation == operation_intersection)
{
return false;
}
@@ -337,7 +347,7 @@ private :
#endif
//debug_consider(0, left, right, header, false, "-> return", ret);
- return left.index < right.index;
+ return default_order(left, right);
}
@@ -347,14 +357,14 @@ private :
//debug_consider(0, left, right, header);
// In general, order it like "union, intersection".
- if (left.subject.operation == operation_intersection
- && right.subject.operation == operation_union)
+ 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)
+ else if (left.subject->operation == operation_union
+ && right.subject->operation == operation_intersection)
{
//debug_consider(0, left, right, header, false, "u,i", true);
return true;
@@ -370,11 +380,17 @@ private :
// 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)
+ if (left.subject->operation == operation_union
+ && right.subject->operation == operation_union)
{
- bool ret = side_si_r == 1;
+ int const side_ri_s = m_strategy.apply(si, sj, ri);
+ if (side_si_r == side_ri_s)
+ {
+ return default_order(left, right);
+ }
+
+ // Take the most left one
+ bool const ret = side_si_r == 1;
//debug_consider(0, left, right, header, false, "same side", ret);
return ret;
}
@@ -408,6 +424,12 @@ private :
// One coming from left (#90, #94, #95)
if (side_si_r != 0 && (side_ri_p != 0 || side_si_p != 0))
{
+ int const side_ri_s = m_strategy.apply(si, sj, ri);
+ if (side_si_r == side_ri_s)
+ {
+ return default_order(left, right);
+ }
+
bool ret = false;
#if BOOST_GEOMETRY_HANDLE_TANGENCIES_WITH_OVERLAP_INFO
@@ -456,7 +478,7 @@ private :
#if defined(BOOST_GEOMETRY_DEBUG_HANDLE_TANGENCIES)
std::cout << " iu/iu unhandled" << std::endl;
- debug_consider(0, left, right, header, false, "unhandled", left.index < right.index);
+ debug_consider(0, left, right, header, false, "unhandled", left.turn_index < right.turn_index);
#endif
if (! redo)
{
@@ -465,7 +487,7 @@ private :
return ! consider_iu_iu(right, left, header, true);
}
- return left.index < right.index;
+ return default_order(left, right);
}
inline bool consider_ii(Indexed const& left, Indexed const& right,
@@ -489,89 +511,87 @@ private :
bool const ret = side_si_r != 1;
return ret;
}
- return left.index < right.index;
+ return default_order(left, right);
}
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))
+ if ((m_turn_points[left.turn_index].discarded || left.discarded)
+ && (m_turn_points[right.turn_index].discarded || right.discarded))
{
- return default_order;
+ return default_order(left, right);
}
- else if (m_turn_points[left.index].discarded || left.discarded)
+ else if (m_turn_points[left.turn_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)
+ else if (m_turn_points[right.turn_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))
+ else if (m_turn_points[left.turn_index].combination(operation_blocked, operation_union)
+ && m_turn_points[right.turn_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))
+ else if (m_turn_points[left.turn_index].both(operation_union)
+ && m_turn_points[right.turn_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;
+ return default_order(left, right);
}
- else if (m_turn_points[left.index].combination(operation_intersection, operation_union)
- && m_turn_points[right.index].combination(operation_intersection, operation_union))
+ else if (m_turn_points[left.turn_index].combination(operation_intersection, operation_union)
+ && m_turn_points[right.turn_index].combination(operation_intersection, operation_union))
{
return consider_iu_iu(left, right, "iu/iu");
}
- else if (m_turn_points[left.index].combination(operation_intersection, operation_blocked)
- && m_turn_points[right.index].combination(operation_intersection, operation_blocked))
+ else if (m_turn_points[left.turn_index].combination(operation_intersection, operation_blocked)
+ && m_turn_points[right.turn_index].combination(operation_intersection, operation_blocked))
{
return consider_ix_ix(left, right, "ix/ix");
}
- else if (m_turn_points[left.index].both(operation_intersection)
- && m_turn_points[right.index].both(operation_intersection))
+ else if (m_turn_points[left.turn_index].both(operation_intersection)
+ && m_turn_points[right.turn_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))
+ else if (m_turn_points[left.turn_index].combination(operation_union, operation_blocked)
+ && m_turn_points[right.turn_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))
+ else if (m_turn_points[left.turn_index].combination(operation_intersection, operation_union)
+ && m_turn_points[right.turn_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))
+ else if (m_turn_points[left.turn_index].combination(operation_intersection, operation_blocked)
+ && m_turn_points[right.turn_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))
+ else if (m_turn_points[left.turn_index].combination(operation_intersection, operation_union)
+ && m_turn_points[right.turn_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
+ else if (m_turn_points[left.turn_index].method != method_equal
+ && m_turn_points[right.turn_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
+ else if (m_turn_points[left.turn_index].method == method_equal
+ && m_turn_points[right.turn_index].method != method_equal
)
{
return true;
@@ -580,15 +600,15 @@ public :
// Now we have no clue how to sort.
#if defined(BOOST_GEOMETRY_DEBUG_HANDLE_TANGENCIES)
- 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 << " Consider: " << operation_char(m_turn_points[left.turn_index].operations[0].operation)
+ << operation_char(m_turn_points[left.turn_index].operations[1].operation)
+ << "/" << operation_char(m_turn_points[right.turn_index].operations[0].operation)
+ << operation_char(m_turn_points[right.turn_index].operations[1].operation)
+ << " " << " Take " << left.turn_index << " < " << right.turn_index
<< std::endl;
#endif
- return default_order;
+ return default_order(left, right);
}
};
@@ -615,8 +635,8 @@ inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster,
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;
+ operation_type first = turn_points[it->turn_index].operations[0].operation;
+ operation_type second = turn_points[it->turn_index].operations[1].operation;
if (first > second)
{
std::swap(first, second);
@@ -645,7 +665,7 @@ inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster,
// 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))
+ if (turn_points[it->turn_index].combination(operation_intersection, operation_union))
{
it->discarded = true;
}
@@ -661,7 +681,7 @@ inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster,
if (! it->discarded)
{
nd_count++;
- if (turn_points[it->index].both(operation_continue))
+ if (turn_points[it->turn_index].both(operation_continue))
{
cc_count++;
}
@@ -677,7 +697,7 @@ inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster,
{
for (Iterator it = begin_cluster; it != end_cluster; ++it)
{
- if (turn_points[it->index].both(operation_continue))
+ if (turn_points[it->turn_index].both(operation_continue))
{
it->discarded = true;
}
@@ -709,7 +729,7 @@ inline void handle_cluster(Iterator begin_cluster, Iterator end_cluster,
for_operation, geometry1, geometry2, strategy);
- // Then sort this range (discard rows will be ordered first and will be removed in enrich_assign)
+ // Then sort this range (discarded rows will be ordered first and will be removed in enrich_assign)
std::sort(begin_cluster, end_cluster,
sort_in_cluster
<
@@ -723,24 +743,24 @@ inline void handle_cluster(Iterator begin_cluster, Iterator end_cluster,
#if defined(BOOST_GEOMETRY_DEBUG_HANDLE_TANGENCIES)
typedef typename IndexType::type operations_type;
- operations_type const& op = turn_points[begin_cluster->index].operations[begin_cluster->operation_index];
+ operations_type const& op = turn_points[begin_cluster->turn_index].operations[begin_cluster->operation_index];
std::cout << std::endl << "Clustered points on equal distance " << op.fraction << std::endl;
std::cout << "->Indexes ";
for (Iterator it = begin_cluster; it != end_cluster; ++it)
{
- std::cout << " " << it->index;
+ std::cout << " " << it->turn_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 << " " << method_char(turn_points[it->turn_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 << " " << operation_char(turn_points[it->turn_index].operations[0].operation)
+ << operation_char(turn_points[it->turn_index].operations[1].operation);
}
std::cout << std::endl << "->Discarded: ";
for (Iterator it = begin_cluster; it != end_cluster; ++it)
@@ -750,7 +770,7 @@ inline void handle_cluster(Iterator begin_cluster, Iterator end_cluster,
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)
+ //<< geometry::distance(turn_points[prev->turn_index].point, turn_points[it->turn_index].point)
#endif
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
index a13a627456..5b9562674a 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
@@ -1,9 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -42,10 +42,11 @@
#include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
-
+#include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
-#include <boost/foreach.hpp>
+#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
+#include <boost/geometry/io/wkt/wkt.hpp>
#endif
namespace boost { namespace geometry
@@ -254,9 +255,10 @@ struct intersection_of_linestring_with_areal
#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
int index = 0;
- BOOST_FOREACH(turn_info const& turn, turns)
+ for(typename std::deque<turn_info>::const_iterator
+ it = turns.begin(); it != turns.end(); ++it)
{
- debug_follow(turn, turn.operations[0], index++);
+ debug_follow(*it, it->operations[0], index++);
}
#endif
@@ -408,13 +410,13 @@ struct intersection_insert
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Linestring const& linestring,
Box const& box,
- RobustPolicy const& ,
+ RobustPolicy const& robust_policy,
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);
+ <GeometryOut>(box, linestring, robust_policy, out, lb_strategy);
}
};
@@ -486,7 +488,7 @@ struct intersection_insert
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Segment const& segment,
Box const& box,
- RobustPolicy const& ,// TODO: propagate to clip_range_with_box
+ RobustPolicy const& robust_policy,
OutputIterator out, Strategy const& )
{
geometry::segment_view<Segment> range(segment);
@@ -494,7 +496,7 @@ struct intersection_insert
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);
+ <GeometryOut>(box, range, robust_policy, out, lb_strategy);
}
};
@@ -699,6 +701,79 @@ struct intersection_insert
{};
+// dispatch for difference/intersection of pointlike-linear geometries
+template
+<
+ typename Point, typename Linear, typename PointOut,
+ overlay_type OverlayType,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename Tag
+>
+struct intersection_insert
+ <
+ Point, Linear, PointOut, OverlayType,
+ Reverse1, Reverse2, ReverseOut,
+ point_tag, Tag, point_tag,
+ false, false, false
+ > : detail_dispatch::overlay::pointlike_linear_point
+ <
+ Point, Linear, PointOut, OverlayType,
+ point_tag, typename tag_cast<Tag, segment_tag, linear_tag>::type
+ >
+{};
+
+
+template
+<
+ typename MultiPoint, typename Linear, typename PointOut,
+ overlay_type OverlayType,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename Tag
+>
+struct intersection_insert
+ <
+ MultiPoint, Linear, PointOut, OverlayType,
+ Reverse1, Reverse2, ReverseOut,
+ multi_point_tag, Tag, point_tag,
+ false, false, false
+ > : detail_dispatch::overlay::pointlike_linear_point
+ <
+ MultiPoint, Linear, PointOut, OverlayType,
+ multi_point_tag,
+ typename tag_cast<Tag, segment_tag, linear_tag>::type
+ >
+{};
+
+
+template
+<
+ typename Linestring, typename MultiPoint, typename PointOut,
+ bool Reverse1, bool Reverse2, bool ReverseOut
+>
+struct intersection_insert
+ <
+ Linestring, MultiPoint, PointOut, overlay_intersection,
+ Reverse1, Reverse2, ReverseOut,
+ linestring_tag, multi_point_tag, point_tag,
+ false, false, false
+ >
+{
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(Linestring const& linestring,
+ MultiPoint const& multipoint,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ return detail_dispatch::overlay::pointlike_linear_point
+ <
+ MultiPoint, Linestring, PointOut, overlay_intersection,
+ multi_point_tag, linear_tag
+ >::apply(multipoint, linestring, robust_policy, out, strategy);
+ }
+};
+
+
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
index 3a7a7a7f3e..73cef84c69 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -144,11 +144,10 @@ protected:
typename Info,
typename Point1,
typename Point2,
- typename IntersectionInfo,
- typename DirInfo
+ typename IntersectionInfo
>
static inline void apply(Info& , Point1 const& , Point2 const& ,
- IntersectionInfo const& , DirInfo const& )
+ IntersectionInfo const& )
{
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/overlay.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/overlay.hpp
index 29e0dad0ce..baf9d4777d 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/overlay.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/overlay.hpp
@@ -1,7 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -28,7 +33,7 @@
#include <boost/geometry/algorithms/detail/recalculate.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/reverse.hpp>
#include <boost/geometry/algorithms/detail/overlay/add_rings.hpp>
@@ -44,10 +49,6 @@
# include <boost/geometry/io/dsv/write.hpp>
#endif
-#ifdef BOOST_GEOMETRY_TIME_OVERLAY
-# include <boost/timer.hpp>
-#endif
-
namespace boost { namespace geometry
{
@@ -57,44 +58,45 @@ namespace boost { namespace geometry
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)
+template <typename TurnPoints, typename TurnInfoMap>
+inline void get_ring_turn_info(TurnInfoMap& turn_info_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)
+ ++it)
{
- if (! skip(*it))
+ typename boost::range_value<TurnPoints>::type const& turn_info = *it;
+ bool both_uu = turn_info.both(operation_union);
+ bool skip = (turn_info.discarded || both_uu)
+ && ! turn_info.any_blocked()
+ && ! turn_info.both(operation_intersection)
+ ;
+
+ for (typename boost::range_iterator<container_type const>::type
+ op_it = boost::begin(turn_info.operations);
+ op_it != boost::end(turn_info.operations);
+ ++op_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
+ );
+
+ if (! skip)
+ {
+ turn_info_map[ring_id].has_normal_turn = true;
+ }
+ else if (both_uu)
{
- 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]++;
+ turn_info_map[ring_id].has_uu_turn = true;
}
}
}
@@ -128,8 +130,7 @@ inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
// Intersection: return nothing
// Difference: return first of them
if (Direction == overlay_intersection
- || (Direction == overlay_difference
- && geometry::num_points(geometry1) == 0))
+ || (Direction == overlay_difference && geometry::is_empty(geometry1)))
{
return out;
}
@@ -139,10 +140,10 @@ inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
#endif
- std::map<ring_identifier, int> empty;
+ std::map<ring_identifier, ring_turn_info> empty;
std::map<ring_identifier, properties> all_of_one_of_them;
- select_rings<Direction>(geometry1, geometry2, empty, all_of_one_of_them, false);
+ select_rings<Direction>(geometry1, geometry2, empty, all_of_one_of_them);
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);
@@ -165,14 +166,15 @@ struct overlay
OutputIterator out,
Strategy const& )
{
- if ( geometry::num_points(geometry1) == 0
- && geometry::num_points(geometry2) == 0 )
+ bool const is_empty1 = geometry::is_empty(geometry1);
+ bool const is_empty2 = geometry::is_empty(geometry2);
+
+ if (is_empty1 && is_empty2)
{
return out;
}
- if ( geometry::num_points(geometry1) == 0
- || geometry::num_points(geometry2) == 0 )
+ if (is_empty1 || is_empty2)
{
return return_if_one_input_is_empty
<
@@ -195,10 +197,6 @@ struct overlay
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
@@ -209,10 +207,6 @@ std::cout << "get turns" << std::endl;
detail::overlay::assign_null_policy
>(geometry1, geometry2, robust_policy, 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
@@ -225,11 +219,6 @@ std::cout << "enrich" << std::endl;
robust_policy,
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
@@ -247,27 +236,18 @@ std::cout << "traverse" << std::endl;
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, ring_turn_info> turn_info_per_ring;
+ get_ring_turn_info(turn_info_per_ring, turn_points);
- 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
+ typedef ring_properties
+ <
+ typename geometry::point_type<GeometryOut>::type
+ > properties;
+ // Select all rings which are NOT touched by any intersection point
+ std::map<ring_identifier, properties> selected_ring_properties;
+ select_rings<Direction>(geometry1, geometry2, turn_info_per_ring,
+ selected_ring_properties);
// Add rings created during traversal
{
@@ -277,24 +257,15 @@ std::cout << "traverse" << std::endl;
it != boost::end(rings);
++it)
{
- selected[id] = properties(*it, true);
- selected[id].reversed = ReverseOut;
+ selected_ring_properties[id] = properties(*it);
+ selected_ring_properties[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
+ assign_parents(geometry1, geometry2, rings, selected_ring_properties);
- return add_rings<GeometryOut>(selected, geometry1, geometry2, rings, out);
+ return add_rings<GeometryOut>(selected_ring_properties, geometry1, geometry2, rings, out);
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
new file mode 100644
index 0000000000..156cb54867
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
@@ -0,0 +1,343 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
+
+#include <iterator>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/algorithms/detail/not.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
+#include <boost/geometry/algorithms/detail/relate/less.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
+#include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+// action struct for pointlike-linear difference/intersection
+// it works the same as its pointlike-pointlike counterpart, hence the
+// derivation
+template <typename PointOut, overlay_type OverlayType>
+struct action_selector_pl_l
+ : action_selector_pl_pl<PointOut, OverlayType>
+{};
+
+// difference/intersection of point-linear
+template
+<
+ typename Point,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Policy
+>
+struct point_linear_point
+{
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(Point const& point,
+ Linear const& linear,
+ RobustPolicy const&,
+ OutputIterator oit,
+ Strategy const&)
+ {
+ action_selector_pl_l
+ <
+ PointOut, OverlayType
+ >::apply(point, Policy::apply(point, linear), oit);
+ return oit;
+ }
+};
+
+// difference/intersection of multipoint-segment
+template
+<
+ typename MultiPoint,
+ typename Segment,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Policy
+>
+struct multipoint_segment_point
+{
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(MultiPoint const& multipoint,
+ Segment const& segment,
+ RobustPolicy const&,
+ OutputIterator oit,
+ Strategy const&)
+ {
+ for (typename boost::range_iterator<MultiPoint const>::type
+ it = boost::begin(multipoint);
+ it != boost::end(multipoint);
+ ++it)
+ {
+ action_selector_pl_l
+ <
+ PointOut, OverlayType
+ >::apply(*it, Policy::apply(*it, segment), oit);
+ }
+
+ return oit;
+ }
+};
+
+
+// difference/intersection of multipoint-linear
+template
+<
+ typename MultiPoint,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Policy
+>
+class multipoint_linear_point
+{
+private:
+ // structs for partition -- start
+ struct expand_box
+ {
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& total, Geometry const& geometry)
+ {
+ geometry::expand(total, geometry::return_envelope<Box>(geometry));
+ }
+
+ };
+
+ struct overlaps_box
+ {
+ template <typename Box, typename Geometry>
+ static inline bool apply(Box const& box, Geometry const& geometry)
+ {
+ return ! geometry::disjoint(geometry, box);
+ }
+ };
+
+ template <typename OutputIterator>
+ class item_visitor_type
+ {
+ public:
+ item_visitor_type(OutputIterator& oit) : m_oit(oit) {}
+
+ template <typename Item1, typename Item2>
+ inline void apply(Item1 const& item1, Item2 const& item2)
+ {
+ action_selector_pl_l
+ <
+ PointOut, overlay_intersection
+ >::apply(item1, Policy::apply(item1, item2), m_oit);
+ }
+
+ private:
+ OutputIterator& m_oit;
+ };
+ // structs for partition -- end
+
+ class segment_range
+ {
+ public:
+ typedef geometry::segment_iterator<Linear const> const_iterator;
+ typedef const_iterator iterator;
+
+ segment_range(Linear const& linear)
+ : m_linear(linear)
+ {}
+
+ const_iterator begin() const
+ {
+ return geometry::segments_begin(m_linear);
+ }
+
+ const_iterator end() const
+ {
+ return geometry::segments_end(m_linear);
+ }
+
+ private:
+ Linear const& m_linear;
+ };
+
+ template <typename OutputIterator>
+ static inline OutputIterator get_common_points(MultiPoint const& multipoint,
+ Linear const& linear,
+ OutputIterator oit)
+ {
+ item_visitor_type<OutputIterator> item_visitor(oit);
+
+ segment_range rng(linear);
+
+ geometry::partition
+ <
+ geometry::model::box
+ <
+ typename boost::range_value<MultiPoint>::type
+ >,
+ expand_box,
+ overlaps_box
+ >::apply(multipoint, rng, item_visitor);
+
+ return oit;
+ }
+
+public:
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(MultiPoint const& multipoint,
+ Linear const& linear,
+ RobustPolicy const& robust_policy,
+ OutputIterator oit,
+ Strategy const& strategy)
+ {
+ typedef std::vector
+ <
+ typename boost::range_value<MultiPoint>::type
+ > point_vector_type;
+
+ point_vector_type common_points;
+
+ // compute the common points
+ get_common_points(multipoint, linear,
+ std::back_inserter(common_points));
+
+ return multipoint_multipoint_point
+ <
+ MultiPoint, point_vector_type, PointOut, OverlayType
+ >::apply(multipoint, common_points, robust_policy, oit, strategy);
+ }
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace detail_dispatch { namespace overlay
+{
+
+// dispatch struct for pointlike-linear difference/intersection computation
+template
+<
+ typename PointLike,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Tag1,
+ typename Tag2
+>
+struct pointlike_linear_point
+ : not_implemented<PointLike, Linear, PointOut>
+{};
+
+
+template
+<
+ typename Point,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ Point, Linear, PointOut, OverlayType, point_tag, linear_tag
+ > : detail::overlay::point_linear_point
+ <
+ Point, Linear, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+template
+<
+ typename Point,
+ typename Segment,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ Point, Segment, PointOut, OverlayType, point_tag, segment_tag
+ > : detail::overlay::point_linear_point
+ <
+ Point, Segment, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+template
+<
+ typename MultiPoint,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ MultiPoint, Linear, PointOut, OverlayType, multi_point_tag, linear_tag
+ > : detail::overlay::multipoint_linear_point
+ <
+ MultiPoint, Linear, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+template
+<
+ typename MultiPoint,
+ typename Segment,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ MultiPoint, Segment, PointOut, OverlayType, multi_point_tag, segment_tag
+ > : detail::overlay::multipoint_segment_point
+ <
+ MultiPoint, Segment, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+}} // namespace detail_dispatch::overlay
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp
index 0af062d271..438a377876 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -14,9 +14,9 @@
#include <algorithm>
#include <vector>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -182,7 +182,7 @@ struct multipoint_point_point
OutputIterator oit,
Strategy const&)
{
- BOOST_ASSERT( OverlayType == overlay_difference );
+ BOOST_GEOMETRY_ASSERT( OverlayType == overlay_difference );
for (typename boost::range_iterator<MultiPoint const>::type
it = boost::begin(multipoint);
@@ -264,7 +264,7 @@ struct multipoint_multipoint_point
>::apply(multipoint2, multipoint1, robust_policy, oit, strategy);
}
- std::vector<typename point_type<MultiPoint2>::type>
+ std::vector<typename boost::range_value<MultiPoint2>::type>
points2(boost::begin(multipoint2), boost::end(multipoint2));
std::sort(points2.begin(), points2.end(), detail::relate::less());
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/ring_properties.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
index a6088694da..0f2da67b62 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
@@ -29,12 +29,13 @@ struct ring_properties
typedef Point point_type;
typedef typename default_area_result<Point>::type area_type;
+ bool valid;
+
// Filled by "select_rings"
Point point;
area_type area;
- // Filled by "update_selection_map"
- int within_code;
+ // Filled by "update_ring_selection"
bool reversed;
// Filled/used by "assign_rings"
@@ -44,22 +45,24 @@ struct ring_properties
std::vector<ring_identifier> children;
inline ring_properties()
- : area(area_type())
- , within_code(-1)
+ : valid(false)
+ , area(area_type())
, 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)
+ inline ring_properties(RingOrBox const& ring_or_box)
+ : reversed(false)
, discarded(false)
, parent_area(-1)
{
this->area = geometry::area(ring_or_box);
- geometry::point_on_border(this->point, ring_or_box, midpoint);
+ // We should take a point somewhere in the middle of the ring,
+ // to avoid taking a point on a (self)tangency,
+ // in cases where multiple points come together
+ valid = geometry::point_on_border(this->point, ring_or_box, true);
}
inline area_type get_area() const
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
index 007113ffba..516ec349e8 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
@@ -14,19 +14,19 @@
# define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
#endif
+#if defined(BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER)
+#include <iostream>
+#endif
-#include <vector>
-
-
-#include <boost/geometry/core/access.hpp>
-#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
namespace boost { namespace geometry
{
+
// Internal struct to uniquely identify a segment
// on a linestring,ring
// or polygon (needs ring_index)
@@ -40,7 +40,10 @@ struct segment_identifier
, segment_index(-1)
{}
- inline segment_identifier(int src, int mul, int rin, int seg)
+ inline segment_identifier(signed_index_type src,
+ signed_index_type mul,
+ signed_index_type rin,
+ signed_index_type seg)
: source_index(src)
, multi_index(mul)
, ring_index(rin)
@@ -68,20 +71,20 @@ struct segment_identifier
#if defined(BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER)
friend std::ostream& operator<<(std::ostream &os, segment_identifier const& seg_id)
{
- std::cout
+ os
<< "s:" << seg_id.source_index
- << ", v:" << seg_id.segment_index // ~vertex
+ << ", v:" << seg_id.segment_index // v:vertex because s is used for source
;
- 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;
+ if (seg_id.ring_index >= 0) os << ", r:" << seg_id.ring_index;
+ if (seg_id.multi_index >= 0) os << ", m:" << seg_id.multi_index;
return os;
}
#endif
- int source_index;
- int multi_index;
- int ring_index;
- int segment_index;
+ signed_index_type source_index;
+ signed_index_type multi_index;
+ signed_index_type ring_index;
+ signed_index_type segment_index;
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/select_rings.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/select_rings.hpp
index 385658a190..d18e012b2d 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/select_rings.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/select_rings.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// Use, modification and distribution is subject to the Boost Software License,
@@ -20,7 +20,6 @@
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.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>
@@ -34,6 +33,18 @@ namespace boost { namespace geometry
namespace detail { namespace overlay
{
+struct ring_turn_info
+{
+ bool has_uu_turn;
+ bool has_normal_turn;
+ bool within_other;
+
+ ring_turn_info()
+ : has_uu_turn(false)
+ , has_normal_turn(false)
+ , within_other(false)
+ {}
+};
namespace dispatch
{
@@ -45,41 +56,41 @@ namespace dispatch
template <typename Box>
struct select_rings<box_tag, Box>
{
- template <typename Geometry, typename Map>
+ template <typename Geometry, typename RingPropertyMap>
static inline void apply(Box const& box, Geometry const& ,
- ring_identifier const& id, Map& map, bool midpoint)
+ ring_identifier const& id, RingPropertyMap& ring_properties)
{
- map[id] = typename Map::mapped_type(box, midpoint);
+ ring_properties[id] = typename RingPropertyMap::mapped_type(box);
}
- template <typename Map>
+ template <typename RingPropertyMap>
static inline void apply(Box const& box,
- ring_identifier const& id, Map& map, bool midpoint)
+ ring_identifier const& id, RingPropertyMap& ring_properties)
{
- map[id] = typename Map::mapped_type(box, midpoint);
+ ring_properties[id] = typename RingPropertyMap::mapped_type(box);
}
};
template <typename Ring>
struct select_rings<ring_tag, Ring>
{
- template <typename Geometry, typename Map>
+ template <typename Geometry, typename RingPropertyMap>
static inline void apply(Ring const& ring, Geometry const& ,
- ring_identifier const& id, Map& map, bool midpoint)
+ ring_identifier const& id, RingPropertyMap& ring_properties)
{
if (boost::size(ring) > 0)
{
- map[id] = typename Map::mapped_type(ring, midpoint);
+ ring_properties[id] = typename RingPropertyMap::mapped_type(ring);
}
}
- template <typename Map>
+ template <typename RingPropertyMap>
static inline void apply(Ring const& ring,
- ring_identifier const& id, Map& map, bool midpoint)
+ ring_identifier const& id, RingPropertyMap& ring_properties)
{
if (boost::size(ring) > 0)
{
- map[id] = typename Map::mapped_type(ring, midpoint);
+ ring_properties[id] = typename RingPropertyMap::mapped_type(ring);
}
}
};
@@ -88,14 +99,14 @@ namespace dispatch
template <typename Polygon>
struct select_rings<polygon_tag, Polygon>
{
- template <typename Geometry, typename Map>
+ template <typename Geometry, typename RingPropertyMap>
static inline void apply(Polygon const& polygon, Geometry const& geometry,
- ring_identifier id, Map& map, bool midpoint)
+ ring_identifier id, RingPropertyMap& ring_properties)
{
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);
+ per_ring::apply(exterior_ring(polygon), geometry, id, ring_properties);
typename interior_return_type<Polygon const>::type
rings = interior_rings(polygon);
@@ -103,18 +114,18 @@ namespace dispatch
it = boost::begin(rings); it != boost::end(rings); ++it)
{
id.ring_index++;
- per_ring::apply(*it, geometry, id, map, midpoint);
+ per_ring::apply(*it, geometry, id, ring_properties);
}
}
- template <typename Map>
+ template <typename RingPropertyMap>
static inline void apply(Polygon const& polygon,
- ring_identifier id, Map& map, bool midpoint)
+ ring_identifier id, RingPropertyMap& ring_properties)
{
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);
+ per_ring::apply(exterior_ring(polygon), id, ring_properties);
typename interior_return_type<Polygon const>::type
rings = interior_rings(polygon);
@@ -122,7 +133,7 @@ namespace dispatch
it = boost::begin(rings); it != boost::end(rings); ++it)
{
id.ring_index++;
- per_ring::apply(*it, id, map, midpoint);
+ per_ring::apply(*it, id, ring_properties);
}
}
};
@@ -130,9 +141,9 @@ namespace dispatch
template <typename Multi>
struct select_rings<multi_polygon_tag, Multi>
{
- template <typename Geometry, typename Map>
+ template <typename Geometry, typename RingPropertyMap>
static inline void apply(Multi const& multi, Geometry const& geometry,
- ring_identifier id, Map& map, bool midpoint)
+ ring_identifier id, RingPropertyMap& ring_properties)
{
typedef typename boost::range_iterator
<
@@ -145,7 +156,7 @@ namespace dispatch
for (iterator_type it = boost::begin(multi); it != boost::end(multi); ++it)
{
id.ring_index = -1;
- per_polygon::apply(*it, geometry, id, map, midpoint);
+ per_polygon::apply(*it, geometry, id, ring_properties);
id.multi_index++;
}
}
@@ -161,14 +172,12 @@ struct decide
template<>
struct decide<overlay_union>
{
- template <typename Code>
- static bool include(ring_identifier const& , Code const& code)
+ static bool include(ring_identifier const& , ring_turn_info const& info)
{
- return code.within_code * -1 == 1;
+ return info.has_uu_turn || ! info.within_other;
}
- template <typename Code>
- static bool reversed(ring_identifier const& , Code const& )
+ static bool reversed(ring_identifier const& , ring_turn_info const& )
{
return false;
}
@@ -177,31 +186,43 @@ struct decide<overlay_union>
template<>
struct decide<overlay_difference>
{
- template <typename Code>
- static bool include(ring_identifier const& id, Code const& code)
+ static bool include(ring_identifier const& id, ring_turn_info const& info)
{
- bool is_first = id.source_index == 0;
- return code.within_code * -1 * (is_first ? 1 : -1) == 1;
+ // Difference: A - B
+
+ // If this is A (source_index=0) and there is only a u/u turn,
+ // then the ring is inside B
+ // If this is B (source_index=1) and there is only a u/u turn,
+ // then the ring is NOT inside A
+
+ // If this is A and the ring is within the other geometry,
+ // then we should NOT include it.
+ // If this is B then we SHOULD include it.
+
+ bool const is_first = id.source_index == 0;
+ bool const within_other = info.within_other
+ || (is_first && info.has_uu_turn);
+ return is_first ? ! within_other : within_other;
}
- template <typename Code>
- static bool reversed(ring_identifier const& id, Code const& code)
+ static bool reversed(ring_identifier const& id, ring_turn_info const& info)
{
- return include(id, code) && id.source_index == 1;
+ // Difference: A - B
+ // If this is B, and the ring is included, it should be reversed afterwards
+
+ return id.source_index == 1 && include(id, info);
}
};
template<>
struct decide<overlay_intersection>
{
- template <typename Code>
- static bool include(ring_identifier const& , Code const& code)
+ static bool include(ring_identifier const& , ring_turn_info const& info)
{
- return code.within_code * 1 == 1;
+ return ! info.has_uu_turn && info.within_other;
}
- template <typename Code>
- static bool reversed(ring_identifier const& , Code const& )
+ static bool reversed(ring_identifier const& , ring_turn_info const& )
{
return false;
}
@@ -211,61 +232,60 @@ struct decide<overlay_intersection>
template
<
overlay_type OverlayType,
- typename Geometry1, typename Geometry2,
- typename IntersectionMap, typename SelectionMap
+ typename Geometry1,
+ typename Geometry2,
+ typename TurnInfoMap,
+ typename RingPropertyMap
>
-inline void update_selection_map(Geometry1 const& geometry1,
+inline void update_ring_selection(Geometry1 const& geometry1,
Geometry2 const& geometry2,
- IntersectionMap const& intersection_map,
- SelectionMap const& map_with_all, SelectionMap& selection_map)
+ TurnInfoMap const& turn_info_map,
+ RingPropertyMap const& all_ring_properties,
+ RingPropertyMap& selected_ring_properties)
{
- selection_map.clear();
+ selected_ring_properties.clear();
- for (typename SelectionMap::const_iterator it = boost::begin(map_with_all);
- it != boost::end(map_with_all);
+ for (typename RingPropertyMap::const_iterator it = boost::begin(all_ring_properties);
+ it != boost::end(all_ring_properties);
++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;
+
+ ring_turn_info info;
+
+ typename TurnInfoMap::const_iterator tcit = turn_info_map.find(id);
+ if (tcit != turn_info_map.end())
{
- ring_identifier const id = it->first;
- typename SelectionMap::mapped_type properties = it->second; // Copy by value
+ info = tcit->second; // Copy by value
+ }
- // Calculate the "within code" (previously this was done earlier but is
- // much 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
+ if (info.has_normal_turn)
+ {
+ // There are normal turns on this ring. It should be traversed, we
+ // don't include the original ring
+ continue;
+ }
+
+ if (! info.has_uu_turn)
+ {
+ // Check if the ring is within the other geometry, by taking
+ // a point lying on the ring
switch(id.source_index)
{
case 0 :
- properties.within_code
- = geometry::within(properties.point, geometry2) ? 1 : -1;
+ info.within_other = geometry::within(it->second.point, geometry2);
break;
case 1 :
- properties.within_code
- = geometry::within(properties.point, geometry1) ? 1 : -1;
+ info.within_other = geometry::within(it->second.point, geometry1);
break;
}
+ }
- if (decide<OverlayType>::include(id, properties))
- {
- properties.reversed = decide<OverlayType>::reversed(id, properties);
- selection_map[id] = properties;
- }
+ if (decide<OverlayType>::include(id, info))
+ {
+ typename RingPropertyMap::mapped_type properties = it->second; // Copy by value
+ properties.reversed = decide<OverlayType>::reversed(id, info);
+ selected_ring_properties[id] = properties;
}
}
}
@@ -277,44 +297,47 @@ inline void update_selection_map(Geometry1 const& geometry1,
template
<
overlay_type OverlayType,
- typename Geometry1, typename Geometry2,
- typename IntersectionMap, typename SelectionMap
+ typename Geometry1,
+ typename Geometry2,
+ typename RingTurnInfoMap,
+ typename RingPropertyMap
>
inline void select_rings(Geometry1 const& geometry1, Geometry2 const& geometry2,
- IntersectionMap const& intersection_map,
- SelectionMap& selection_map, bool midpoint)
+ RingTurnInfoMap const& turn_info_per_ring,
+ RingPropertyMap& selected_ring_properties)
{
typedef typename geometry::tag<Geometry1>::type tag1;
typedef typename geometry::tag<Geometry2>::type tag2;
- SelectionMap map_with_all;
+ RingPropertyMap all_ring_properties;
dispatch::select_rings<tag1, Geometry1>::apply(geometry1, geometry2,
- ring_identifier(0, -1, -1), map_with_all, midpoint);
+ ring_identifier(0, -1, -1), all_ring_properties);
dispatch::select_rings<tag2, Geometry2>::apply(geometry2, geometry1,
- ring_identifier(1, -1, -1), map_with_all, midpoint);
+ ring_identifier(1, -1, -1), all_ring_properties);
- update_selection_map<OverlayType>(geometry1, geometry2, intersection_map,
- map_with_all, selection_map);
+ update_ring_selection<OverlayType>(geometry1, geometry2, turn_info_per_ring,
+ all_ring_properties, selected_ring_properties);
}
template
<
overlay_type OverlayType,
typename Geometry,
- typename IntersectionMap, typename SelectionMap
+ typename RingTurnInfoMap,
+ typename RingPropertyMap
>
inline void select_rings(Geometry const& geometry,
- IntersectionMap const& intersection_map,
- SelectionMap& selection_map, bool midpoint)
+ RingTurnInfoMap const& turn_info_per_ring,
+ RingPropertyMap& selected_ring_properties)
{
typedef typename geometry::tag<Geometry>::type tag;
- SelectionMap map_with_all;
+ RingPropertyMap all_ring_properties;
dispatch::select_rings<tag, Geometry>::apply(geometry,
- ring_identifier(0, -1, -1), map_with_all, midpoint);
+ ring_identifier(0, -1, -1), all_ring_properties);
- update_selection_map<OverlayType>(geometry, geometry, intersection_map,
- map_with_all, selection_map);
+ update_ring_selection<OverlayType>(geometry, geometry, turn_info_per_ring,
+ all_ring_properties, selected_ring_properties);
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
index 8dffeae283..a74cb83f77 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
@@ -12,6 +12,7 @@
#include <cstddef>
+#include <boost/mpl/vector_c.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
@@ -23,9 +24,12 @@
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/algorithms/detail/sections/section_box_policies.hpp>
#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/util/condition.hpp>
+
namespace boost { namespace geometry
{
@@ -96,7 +100,7 @@ struct self_section_visitor
m_rescale_policy,
m_turns, m_interrupt_policy);
}
- if (m_interrupt_policy.has_intersections)
+ if (BOOST_GEOMETRY_CONDITION(m_interrupt_policy.has_intersections))
{
// TODO: we should give partition an interrupt policy.
// Now we throw, and catch below, to stop the partition loop.
@@ -121,15 +125,19 @@ struct get_turns
{
typedef model::box
<
- typename geometry::point_type<Geometry>::type
+ typename geometry::robust_point_type
+ <
+ typename geometry::point_type<Geometry>::type,
+ RobustPolicy
+ >::type
> box_type;
- typedef typename geometry::sections
- <
- box_type, 1
- > sections_type;
+
+ typedef geometry::sections<box_type, 1> sections_type;
+
+ typedef boost::mpl::vector_c<std::size_t, 0> dimensions;
sections_type sec;
- geometry::sectionalize<false>(geometry, robust_policy, false, sec);
+ geometry::sectionalize<false, dimensions>(geometry, robust_policy, sec);
self_section_visitor
<
@@ -142,8 +150,8 @@ struct get_turns
geometry::partition
<
box_type,
- detail::get_turns::get_section_box,
- detail::get_turns::ovelaps_section_box
+ detail::section::get_section_box,
+ detail::section::overlaps_section_box
>::apply(sec, visitor);
}
catch(self_ip_exception const& )
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/traverse.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/traverse.hpp
index bde86b4d73..e121fe5581 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/traverse.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/traverse.hpp
@@ -18,6 +18,7 @@
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -116,8 +117,8 @@ inline bool assign_next_ip(G1 const& g1, G2 const& g2,
return false;
}
- BOOST_ASSERT(info.enriched.travels_to_vertex_index >= 0);
- BOOST_ASSERT(info.enriched.travels_to_ip_index >= 0);
+ BOOST_GEOMETRY_ASSERT(info.enriched.travels_to_vertex_index >= 0);
+ BOOST_GEOMETRY_ASSERT(info.enriched.travels_to_ip_index >= 0);
if (info.seg_id.source_index == 0)
{
@@ -149,7 +150,9 @@ inline bool assign_next_ip(G1 const& g1, G2 const& g2,
}
-inline bool select_source(operation_type operation, int source1, int source2)
+inline bool select_source(operation_type operation,
+ signed_index_type source1,
+ signed_index_type source2)
{
return (operation == operation_intersection && source1 != source2)
|| (operation == operation_union && source1 == source2)
@@ -324,7 +327,7 @@ public :
detail::overlay::debug_traverse(*current, *current_iit, "Selected ");
- unsigned int i = 0;
+ typename boost::range_size<Turns>::type i = 0;
while (current_iit != iit && state.good())
{
diff --git a/3party/boost/boost/geometry/algorithms/detail/overlay/turn_info.hpp b/3party/boost/boost/geometry/algorithms/detail/overlay/turn_info.hpp
index 91a133789e..26669a4b1f 100644
--- a/3party/boost/boost/geometry/algorithms/detail/overlay/turn_info.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/overlay/turn_info.hpp
@@ -59,7 +59,6 @@ struct turn_operation
{
operation_type operation;
segment_identifier seg_id;
- segment_identifier other_id;
SegmentRatio fraction;
inline turn_operation()
diff --git a/3party/boost/boost/geometry/algorithms/detail/partition.hpp b/3party/boost/boost/geometry/algorithms/detail/partition.hpp
index 8e5f5a15d9..8b19add479 100644
--- a/3party/boost/boost/geometry/algorithms/detail/partition.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/partition.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,10 +14,13 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
+#include <cstddef>
#include <vector>
-#include <boost/range/algorithm/copy.hpp>
-#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/range.hpp>
+#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+
namespace boost { namespace geometry
{
@@ -20,10 +28,8 @@ namespace boost { namespace geometry
namespace detail { namespace partition
{
-typedef std::vector<std::size_t> index_vector_type;
-
template <int Dimension, typename Box>
-void divide_box(Box const& box, Box& lower_box, Box& upper_box)
+inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
{
typedef typename coordinate_type<Box>::type ctype;
@@ -38,31 +44,26 @@ void divide_box(Box const& box, Box& lower_box, Box& upper_box)
geometry::set<min_corner, Dimension>(upper_box, mid);
}
-// Divide collection into three subsets: lower, upper and oversized
+// Divide forward_range into three subsets: lower, upper and oversized
// (not-fitting)
// (lower == left or bottom, upper == right or top)
-template <typename OverlapsPolicy, typename InputCollection, typename Box>
+template <typename OverlapsPolicy, typename Box, typename IteratorVector>
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)
+ IteratorVector const& input,
+ IteratorVector& lower,
+ IteratorVector& upper,
+ IteratorVector& exceeding)
{
- typedef boost::range_iterator
+ typedef typename boost::range_iterator
<
- index_vector_type const
- >::type index_iterator_type;
+ IteratorVector const
+ >::type it_type;
- for(index_iterator_type it = boost::begin(input);
- it != boost::end(input);
- ++it)
+ for(it_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]);
+ bool const lower_overlapping = OverlapsPolicy::apply(lower_box, **it);
+ bool const upper_overlapping = OverlapsPolicy::apply(upper_box, **it);
if (lower_overlapping && upper_overlapping)
{
@@ -78,109 +79,208 @@ inline void divide_into_subsets(Box const& lower_box,
}
else
{
- // Is nowhere! Should not occur!
- BOOST_ASSERT(true);
+ // Is nowhere. That is (since 1.58) possible, it might be
+ // skipped by the OverlapsPolicy to enhance performance
}
}
}
-// Match collection with itself
-template <typename InputCollection, typename Policy>
-inline void handle_one(InputCollection const& collection,
- index_vector_type const& input,
- Policy& policy)
+template
+<
+ typename ExpandPolicy,
+ typename Box,
+ typename IteratorVector
+>
+inline void expand_with_elements(Box& total, IteratorVector const& input)
{
- typedef boost::range_iterator<index_vector_type const>::type
- index_iterator_type;
+ typedef typename boost::range_iterator<IteratorVector const>::type it_type;
+ for(it_type it = boost::begin(input); it != boost::end(input); ++it)
+ {
+ ExpandPolicy::apply(total, **it);
+ }
+}
+
+
+// Match forward_range with itself
+template <typename Policy, typename IteratorVector>
+inline void handle_one(IteratorVector const& input, Policy& policy)
+{
+ if (boost::size(input) == 0)
+ {
+ return;
+ }
+
+ typedef typename boost::range_iterator<IteratorVector const>::type it_type;
+
// Quadratic behaviour at lowest level (lowest quad, or all exceeding)
- for(index_iterator_type it1 = boost::begin(input);
- it1 != boost::end(input);
- ++it1)
+ for (it_type it1 = boost::begin(input); it1 != boost::end(input); ++it1)
{
- index_iterator_type it2 = it1;
- for(++it2; it2 != boost::end(input); ++it2)
+ it_type it2 = it1;
+ for (++it2; it2 != boost::end(input); ++it2)
{
- policy.apply(collection[*it1], collection[*it2]);
+ policy.apply(**it1, **it2);
}
}
}
-// Match collection 1 with collection 2
+// Match forward range 1 with forward range 2
template
<
- typename InputCollection1,
- typename InputCollection2,
- typename Policy
+ typename Policy,
+ typename IteratorVector1,
+ typename IteratorVector2
>
-inline void handle_two(
- InputCollection1 const& collection1, index_vector_type const& input1,
- InputCollection2 const& collection2, index_vector_type const& input2,
+inline void handle_two(IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
Policy& policy)
{
- typedef boost::range_iterator
+ typedef typename boost::range_iterator
+ <
+ IteratorVector1 const
+ >::type iterator_type1;
+
+ typedef typename boost::range_iterator
<
- index_vector_type const
- >::type index_iterator_type;
+ IteratorVector2 const
+ >::type iterator_type2;
- for(index_iterator_type it1 = boost::begin(input1);
+ if (boost::size(input1) == 0 || boost::size(input2) == 0)
+ {
+ return;
+ }
+
+ for(iterator_type1 it1 = boost::begin(input1);
it1 != boost::end(input1);
++it1)
{
- for(index_iterator_type it2 = boost::begin(input2);
+ for(iterator_type2 it2 = boost::begin(input2);
it2 != boost::end(input2);
++it2)
{
- policy.apply(collection1[*it1], collection2[*it2]);
+ policy.apply(**it1, **it2);
}
}
}
+template <typename IteratorVector>
+inline bool recurse_ok(IteratorVector const& input,
+ std::size_t min_elements, std::size_t level)
+{
+ return boost::size(input) >= min_elements
+ && level < 100;
+}
+
+template <typename IteratorVector1, typename IteratorVector2>
+inline bool recurse_ok(IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
+ std::size_t min_elements, std::size_t level)
+{
+ return boost::size(input1) >= min_elements
+ && recurse_ok(input2, min_elements, level);
+}
+
+template
+<
+ typename IteratorVector1,
+ typename IteratorVector2,
+ typename IteratorVector3
+>
+inline bool recurse_ok(IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
+ IteratorVector3 const& input3,
+ std::size_t min_elements, std::size_t level)
+{
+ return boost::size(input1) >= min_elements
+ && recurse_ok(input2, input3, min_elements, level);
+}
+
+template
+<
+ int Dimension,
+ typename Box,
+ typename OverlapsPolicy1,
+ typename OverlapsPolicy2,
+ typename ExpandPolicy1,
+ typename ExpandPolicy2,
+ typename VisitBoxPolicy
+>
+class partition_two_ranges;
+
+
template
<
int Dimension,
typename Box,
typename OverlapsPolicy,
+ typename ExpandPolicy,
typename VisitBoxPolicy
>
-class partition_one_collection
+class partition_one_range
{
- typedef std::vector<std::size_t> index_vector_type;
- typedef typename coordinate_type<Box>::type ctype;
- typedef partition_one_collection
+ template <typename IteratorVector>
+ static inline Box get_new_box(IteratorVector const& input)
+ {
+ Box box;
+ geometry::assign_inverse(box);
+ expand_with_elements<ExpandPolicy>(box, input);
+ return box;
+ }
+
+ template <typename Policy, typename IteratorVector>
+ static inline void next_level(Box const& box,
+ IteratorVector const& input,
+ std::size_t level, std::size_t min_elements,
+ Policy& policy, VisitBoxPolicy& box_policy)
+ {
+ if (recurse_ok(input, min_elements, level))
+ {
+ partition_one_range
<
1 - Dimension,
Box,
OverlapsPolicy,
+ ExpandPolicy,
VisitBoxPolicy
- > sub_divide;
+ >::apply(box, input, level + 1, min_elements, policy, box_policy);
+ }
+ else
+ {
+ handle_one(input, policy);
+ }
+ }
- 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,
+ // Function to switch to two forward ranges if there are
+ // geometries exceeding the separation line
+ template <typename Policy, typename IteratorVector>
+ static inline void next_level2(Box const& box,
+ IteratorVector const& input1,
+ IteratorVector const& input2,
+ std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
- if (boost::size(input) > 0)
+ if (recurse_ok(input1, input2, min_elements, level))
{
- 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);
- }
+ partition_two_ranges
+ <
+ 1 - Dimension,
+ Box,
+ OverlapsPolicy, OverlapsPolicy,
+ ExpandPolicy, ExpandPolicy,
+ VisitBoxPolicy
+ >::apply(box, input1, input2, level + 1, min_elements,
+ policy, box_policy);
+ }
+ else
+ {
+ handle_two(input1, input2, policy);
}
}
public :
- template <typename InputCollection, typename Policy>
+ template <typename Policy, typename IteratorVector>
static inline void apply(Box const& box,
- InputCollection const& collection,
- index_vector_type const& input,
- int level,
+ IteratorVector const& input,
+ std::size_t level,
std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
@@ -189,24 +289,31 @@ public :
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,
+ IteratorVector lower, upper, exceeding;
+ divide_into_subsets<OverlapsPolicy>(lower_box, upper_box,
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);
+ // Get the box of exceeding-only
+ Box exceeding_box = get_new_box(exceeding);
+
+ // Recursively do exceeding elements only, in next dimension they
+ // will probably be less exceeding within the new box
+ next_level(exceeding_box, exceeding, level, min_elements,
+ policy, box_policy);
+
+ // Switch to two forward ranges, combine exceeding with
+ // lower resp upper, but not lower/lower, upper/upper
+ next_level2(exceeding_box, exceeding, lower, level, min_elements,
+ policy, box_policy);
+ next_level2(exceeding_box, exceeding, upper, level, min_elements,
+ policy, box_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);
+ next_level(lower_box, lower, level, min_elements, policy, box_policy);
+ next_level(upper_box, upper, level, min_elements, policy, box_policy);
}
};
@@ -216,64 +323,66 @@ template
typename Box,
typename OverlapsPolicy1,
typename OverlapsPolicy2,
+ typename ExpandPolicy1,
+ typename ExpandPolicy2,
typename VisitBoxPolicy
>
-class partition_two_collections
+class partition_two_ranges
{
- typedef std::vector<std::size_t> index_vector_type;
- typedef typename coordinate_type<Box>::type ctype;
- typedef partition_two_collections
- <
- 1 - Dimension,
- Box,
- OverlapsPolicy1,
- OverlapsPolicy2,
- VisitBoxPolicy
- > sub_divide;
-
template
<
- typename InputCollection1,
- typename InputCollection2,
- typename Policy
+ typename Policy,
+ typename IteratorVector1,
+ typename IteratorVector2
>
static inline void next_level(Box const& box,
- InputCollection1 const& collection1,
- index_vector_type const& input1,
- InputCollection2 const& collection2,
- index_vector_type const& input2,
- int level, std::size_t min_elements,
+ IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
+ std::size_t 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);
- }
- }
+ partition_two_ranges
+ <
+ 1 - Dimension,
+ Box,
+ OverlapsPolicy1,
+ OverlapsPolicy2,
+ ExpandPolicy1,
+ ExpandPolicy2,
+ VisitBoxPolicy
+ >::apply(box, input1, input2, level + 1, min_elements,
+ policy, box_policy);
+ }
+
+ template <typename ExpandPolicy, typename IteratorVector>
+ static inline Box get_new_box(IteratorVector const& input)
+ {
+ Box box;
+ geometry::assign_inverse(box);
+ expand_with_elements<ExpandPolicy>(box, input);
+ return box;
+ }
+
+ template <typename IteratorVector1, typename IteratorVector2>
+ static inline Box get_new_box(IteratorVector1 const& input1,
+ IteratorVector2 const& input2)
+ {
+ Box box = get_new_box<ExpandPolicy1>(input1);
+ expand_with_elements<ExpandPolicy2>(box, input2);
+ return box;
}
public :
template
<
- typename InputCollection1,
- typename InputCollection2,
- typename Policy
+ typename Policy,
+ typename IteratorVector1,
+ typename IteratorVector2
>
static inline void apply(Box const& box,
- InputCollection1 const& collection1, index_vector_type const& input1,
- InputCollection2 const& collection2, index_vector_type const& input2,
- int level,
+ IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
+ std::size_t level,
std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
@@ -282,46 +391,105 @@ public :
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<OverlapsPolicy1>(lower_box, upper_box, collection1,
+ IteratorVector1 lower1, upper1, exceeding1;
+ IteratorVector2 lower2, upper2, exceeding2;
+ divide_into_subsets<OverlapsPolicy1>(lower_box, upper_box,
input1, lower1, upper1, exceeding1);
- divide_into_subsets<OverlapsPolicy2>(lower_box, upper_box, collection2,
+ divide_into_subsets<OverlapsPolicy2>(lower_box, upper_box,
input2, lower2, upper2, exceeding2);
if (boost::size(exceeding1) > 0)
{
// All exceeding from 1 with 2:
- handle_two(collection1, exceeding1, collection2, exceeding2,
- policy);
+
+ if (recurse_ok(exceeding1, exceeding2, min_elements, level))
+ {
+ Box exceeding_box = get_new_box(exceeding1, exceeding2);
+ next_level(exceeding_box, exceeding1, exceeding2, level,
+ min_elements, policy, box_policy);
+ }
+ else
+ {
+ handle_two(exceeding1, 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);
+
+ // (Check sizes of all three forward ranges to avoid recurse into
+ // the same combinations again and again)
+ if (recurse_ok(lower2, upper2, exceeding1, min_elements, level))
+ {
+ Box exceeding_box = get_new_box<ExpandPolicy1>(exceeding1);
+ next_level(exceeding_box, exceeding1, lower2, level,
+ min_elements, policy, box_policy);
+ next_level(exceeding_box, exceeding1, upper2, level,
+ min_elements, policy, box_policy);
+ }
+ else
+ {
+ handle_two(exceeding1, lower2, policy);
+ handle_two(exceeding1, 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);
+ if (recurse_ok(lower1, upper1, exceeding2, min_elements, level))
+ {
+ Box exceeding_box = get_new_box<ExpandPolicy2>(exceeding2);
+ next_level(exceeding_box, lower1, exceeding2, level,
+ min_elements, policy, box_policy);
+ next_level(exceeding_box, upper1, exceeding2, level,
+ min_elements, policy, box_policy);
+ }
+ else
+ {
+ handle_two(lower1, exceeding2, policy);
+ handle_two(upper1, 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);
+ if (recurse_ok(lower1, lower2, min_elements, level))
+ {
+ next_level(lower_box, lower1, lower2, level,
+ min_elements, policy, box_policy);
+ }
+ else
+ {
+ handle_two(lower1, lower2, policy);
+ }
+ if (recurse_ok(upper1, upper2, min_elements, level))
+ {
+ next_level(upper_box, upper1, upper2, level,
+ min_elements, policy, box_policy);
+ }
+ else
+ {
+ handle_two(upper1, upper2, policy);
+ }
}
};
-}} // namespace detail::partition
-
struct visit_no_policy
{
template <typename Box>
- static inline void apply(Box const&, int )
+ static inline void apply(Box const&, std::size_t )
{}
};
+struct include_all_policy
+{
+ template <typename Item>
+ static inline bool apply(Item const&)
+ {
+ return true;
+ }
+};
+
+
+}} // namespace detail::partition
+
template
<
typename Box,
@@ -329,62 +497,73 @@ template
typename OverlapsPolicy1,
typename ExpandPolicy2 = ExpandPolicy1,
typename OverlapsPolicy2 = OverlapsPolicy1,
- typename VisitBoxPolicy = visit_no_policy
+ typename IncludePolicy1 = detail::partition::include_all_policy,
+ typename IncludePolicy2 = detail::partition::include_all_policy,
+ typename VisitBoxPolicy = detail::partition::visit_no_policy
>
class partition
{
- typedef std::vector<std::size_t> index_vector_type;
-
- template <typename ExpandPolicy, typename InputCollection>
- static inline void expand_to_collection(InputCollection const& collection,
- Box& total, index_vector_type& index_vector)
+ template
+ <
+ typename ExpandPolicy,
+ typename IncludePolicy,
+ typename ForwardRange,
+ typename IteratorVector
+ >
+ static inline void expand_to_range(ForwardRange const& forward_range,
+ Box& total, IteratorVector& iterator_vector)
{
- std::size_t index = 0;
- for(typename boost::range_iterator<InputCollection const>::type it
- = boost::begin(collection);
- it != boost::end(collection);
- ++it, ++index)
+ for(typename boost::range_iterator<ForwardRange const>::type it
+ = boost::begin(forward_range);
+ it != boost::end(forward_range);
+ ++it)
{
- ExpandPolicy::apply(total, *it);
- index_vector.push_back(index);
+ if (IncludePolicy::apply(*it))
+ {
+ ExpandPolicy::apply(total, *it);
+ iterator_vector.push_back(it);
+ }
}
}
public :
- template <typename InputCollection, typename VisitPolicy>
- static inline void apply(InputCollection const& collection,
+ template <typename ForwardRange, typename VisitPolicy>
+ static inline void apply(ForwardRange const& forward_range,
VisitPolicy& visitor,
std::size_t min_elements = 16,
- VisitBoxPolicy box_visitor = visit_no_policy()
+ VisitBoxPolicy box_visitor = detail::partition::visit_no_policy()
)
{
- if (std::size_t(boost::size(collection)) > min_elements)
+ typedef typename boost::range_iterator
+ <
+ ForwardRange const
+ >::type iterator_type;
+
+ if (std::size_t(boost::size(forward_range)) > min_elements)
{
- index_vector_type index_vector;
+ std::vector<iterator_type> iterator_vector;
Box total;
assign_inverse(total);
- expand_to_collection<ExpandPolicy1>(collection, total, index_vector);
+ expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range,
+ total, iterator_vector);
- detail::partition::partition_one_collection
+ detail::partition::partition_one_range
<
0, Box,
OverlapsPolicy1,
+ ExpandPolicy1,
VisitBoxPolicy
- >::apply(total, collection, index_vector, 0, min_elements,
- visitor, box_visitor);
+ >::apply(total, iterator_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);
+ for(iterator_type it1 = boost::begin(forward_range);
+ it1 != boost::end(forward_range);
++it1)
{
iterator_type it2 = it1;
- for(++it2; it2 != boost::end(collection); ++it2)
+ for(++it2; it2 != boost::end(forward_range); ++it2)
{
visitor.apply(*it1, *it2);
}
@@ -394,50 +573,55 @@ public :
template
<
- typename InputCollection1,
- typename InputCollection2,
+ typename ForwardRange1,
+ typename ForwardRange2,
typename VisitPolicy
>
- static inline void apply(InputCollection1 const& collection1,
- InputCollection2 const& collection2,
+ static inline void apply(ForwardRange1 const& forward_range1,
+ ForwardRange2 const& forward_range2,
VisitPolicy& visitor,
std::size_t min_elements = 16,
- VisitBoxPolicy box_visitor = visit_no_policy()
+ VisitBoxPolicy box_visitor
+ = detail::partition::visit_no_policy()
)
{
- if (std::size_t(boost::size(collection1)) > min_elements
- && std::size_t(boost::size(collection2)) > min_elements)
+ typedef typename boost::range_iterator
+ <
+ ForwardRange1 const
+ >::type iterator_type1;
+
+ typedef typename boost::range_iterator
+ <
+ ForwardRange2 const
+ >::type iterator_type2;
+
+ if (std::size_t(boost::size(forward_range1)) > min_elements
+ && std::size_t(boost::size(forward_range2)) > min_elements)
{
- index_vector_type index_vector1, index_vector2;
+ std::vector<iterator_type1> iterator_vector1;
+ std::vector<iterator_type2> iterator_vector2;
Box total;
assign_inverse(total);
- expand_to_collection<ExpandPolicy1>(collection1, total, index_vector1);
- expand_to_collection<ExpandPolicy2>(collection2, total, index_vector2);
+ expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range1,
+ total, iterator_vector1);
+ expand_to_range<ExpandPolicy2, IncludePolicy2>(forward_range2,
+ total, iterator_vector2);
- detail::partition::partition_two_collections
+ detail::partition::partition_two_ranges
<
- 0, Box, OverlapsPolicy1, OverlapsPolicy2, VisitBoxPolicy
- >::apply(total,
- collection1, index_vector1,
- collection2, index_vector2,
- 0, min_elements, visitor, box_visitor);
+ 0, Box, OverlapsPolicy1, OverlapsPolicy2,
+ ExpandPolicy1, ExpandPolicy2, VisitBoxPolicy
+ >::apply(total, iterator_vector1, iterator_vector2,
+ 0, min_elements, visitor, box_visitor);
}
else
{
- typedef typename boost::range_iterator
- <
- InputCollection1 const
- >::type iterator_type1;
- typedef typename boost::range_iterator
- <
- InputCollection2 const
- >::type iterator_type2;
- for(iterator_type1 it1 = boost::begin(collection1);
- it1 != boost::end(collection1);
+ for(iterator_type1 it1 = boost::begin(forward_range1);
+ it1 != boost::end(forward_range1);
++it1)
{
- for(iterator_type2 it2 = boost::begin(collection2);
- it2 != boost::end(collection2);
+ for(iterator_type2 it2 = boost::begin(forward_range2);
+ it2 != boost::end(forward_range2);
++it2)
{
visitor.apply(*it1, *it2);
diff --git a/3party/boost/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp b/3party/boost/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp
index cd3acb5ba4..9db1ef8e0c 100644
--- a/3party/boost/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp
@@ -17,6 +17,7 @@
#include <boost/geometry/algorithms/detail/recalculate.hpp>
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
@@ -91,7 +92,7 @@ static inline bool point_is_spike_or_equal(Point1 const& last_point,
return true;
}
- if (! RobustPolicy::enabled)
+ if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled))
{
return false;
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/recalculate.hpp b/3party/boost/boost/geometry/algorithms/detail/recalculate.hpp
index 2c3ea7413b..056f7c6e1d 100644
--- a/3party/boost/boost/geometry/algorithms/detail/recalculate.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/recalculate.hpp
@@ -21,6 +21,7 @@
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/numeric/conversion/cast.hpp>
+#include <boost/range.hpp>
#include <boost/type_traits.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/areal_areal.hpp
index 1896b0ffa7..78fbb8ee84 100644
--- a/3party/boost/boost/geometry/algorithms/detail/relate/areal_areal.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/areal_areal.hpp
@@ -2,19 +2,21 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_AREAL_AREAL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_AREAL_AREAL_HPP
#include <boost/geometry/core/topological_dimension.hpp>
+
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
@@ -86,7 +88,7 @@ public:
// TODO: This is O(N)
// Run in a loop O(NM) - optimize!
int const pig = detail::within::point_in_geometry(pt, m_other_areal);
- //BOOST_ASSERT( pig != 0 );
+ //BOOST_GEOMETRY_ASSERT( pig != 0 );
// inside
if ( pig > 0 )
@@ -197,7 +199,7 @@ struct areal_areal
// The result should be FFFFFFFFF
relate::set<exterior, exterior, result_dimension<Geometry2>::value>(result);// FFFFFFFFd, d in [1,9] or T
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
// get and analyse turns
@@ -207,17 +209,17 @@ struct areal_areal
interrupt_policy_areal_areal<Result> interrupt_policy(geometry1, geometry2, result);
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
no_turns_aa_pred<Geometry2, Result, false> pred1(geometry2, result);
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
no_turns_aa_pred<Geometry1, Result, true> pred2(geometry1, result);
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
if ( turns.empty() )
@@ -230,7 +232,7 @@ struct areal_areal
|| may_update<exterior, interior, '2'>(result) )
{
// sort turns
- typedef turns::less<0, turns::less_op_areal_areal> less;
+ typedef turns::less<0, turns::less_op_areal_areal<0> > less;
std::sort(turns.begin(), turns.end(), less());
/*if ( may_update<interior, exterior, '2'>(result)
@@ -242,7 +244,7 @@ struct areal_areal
turns_analyser<turn_type, 0> analyser;
analyse_each_turn(result, analyser, turns.begin(), turns.end());
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
}
@@ -257,7 +259,7 @@ struct areal_areal
uncertain_rings_analyser<0, Result, Geometry1, Geometry2> rings_analyser(result, geometry1, geometry2);
analyse_uncertain_rings<0>::apply(rings_analyser, turns.begin(), turns.end());
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
}
}
@@ -269,7 +271,7 @@ struct areal_areal
|| may_update<exterior, interior, '2', true>(result) )
{
// sort turns
- typedef turns::less<1, turns::less_op_areal_areal> less;
+ typedef turns::less<1, turns::less_op_areal_areal<1> > less;
std::sort(turns.begin(), turns.end(), less());
/*if ( may_update<interior, exterior, '2', true>(result)
@@ -281,7 +283,7 @@ struct areal_areal
turns_analyser<turn_type, 1> analyser;
analyse_each_turn(result, analyser, turns.begin(), turns.end());
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
}
@@ -403,7 +405,7 @@ struct areal_areal
typename TurnIt>
void apply(Result & result, TurnIt it)
{
- //BOOST_ASSERT( it != last );
+ //BOOST_GEOMETRY_ASSERT( it != last );
overlay::operation_type const op = it->operations[op_id].operation;
@@ -496,7 +498,7 @@ struct areal_areal
template <typename Result>
void apply(Result & result)
{
- //BOOST_ASSERT( first != last );
+ //BOOST_GEOMETRY_ASSERT( first != last );
if ( m_exit_detected /*m_previous_operation == overlay::operation_union*/ )
{
@@ -549,7 +551,7 @@ struct areal_areal
{
analyser.apply(res, it);
- if ( res.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(res.interrupt) )
return;
}
@@ -573,8 +575,7 @@ struct areal_areal
{
// check which relations must be analysed
- if ( ! may_update<interior, interior, '2', transpose_result>(m_result)
- && ! may_update<boundary, interior, '1', transpose_result>(m_result) )
+ if ( ! may_update<interior, interior, '2', transpose_result>(m_result) )
{
m_flags |= 1;
}
@@ -595,7 +596,7 @@ struct areal_areal
inline void no_turns(segment_identifier const& seg_id)
{
// if those flags are set nothing will change
- if ( (m_flags & 3) == 3 )
+ if ( m_flags == 7 )
{
return;
}
@@ -614,15 +615,18 @@ struct areal_areal
// to know which other single geometries should be checked
// TODO: optimize! e.g. use spatial index
- // O(N) - running it in a loop would gives O(NM)
+ // O(N) - running it in a loop gives O(NM)
int const pig = detail::within::point_in_geometry(range::front(range_ref), other_geometry);
- //BOOST_ASSERT(pig != 0);
+ //BOOST_GEOMETRY_ASSERT(pig != 0);
if ( pig > 0 )
{
- update<boundary, interior, '1', transpose_result>(m_result);
update<interior, interior, '2', transpose_result>(m_result);
m_flags |= 1;
+
+ update<boundary, interior, '1', transpose_result>(m_result);
+ update<exterior, interior, '2', transpose_result>(m_result);
+ m_flags |= 4;
}
else
{
@@ -696,12 +700,6 @@ struct areal_areal
update<boundary, exterior, '1', transpose_result>(m_result);
update<interior, exterior, '2', transpose_result>(m_result);
m_flags |= 2;
-
- // not necessary since this will be checked in the next iteration
- // but increases the pruning strength
- // WARNING: this is not reflected in flags
- update<exterior, boundary, '1', transpose_result>(m_result);
- update<exterior, interior, '2', transpose_result>(m_result);
}
interrupt = m_flags == 7 || m_result.interrupt; // interrupt if the result won't be changed in the future
@@ -795,7 +793,8 @@ struct areal_areal
{
segment_identifier const& seg_id = turn.operations[OpId].seg_id;
- int count = boost::numeric_cast<int>(
+ signed_index_type
+ count = boost::numeric_cast<signed_index_type>(
geometry::num_interior_rings(
detail::single_geometry(analyser.geometry, seg_id)));
@@ -803,7 +802,10 @@ struct areal_areal
}
template <typename Analyser, typename Turn>
- static inline void for_no_turns_rings(Analyser & analyser, Turn const& turn, int first, int last)
+ static inline void for_no_turns_rings(Analyser & analyser,
+ Turn const& turn,
+ signed_index_type first,
+ signed_index_type last)
{
segment_identifier seg_id = turn.operations[OpId].seg_id;
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/boundary_checker.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
index f98c3e9b82..9de1bacb7d 100644
--- a/3party/boost/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
@@ -47,7 +47,7 @@ public:
boost::ignore_unused_variable_warning(pt);
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
// may give false positives for INT
- BOOST_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
+ BOOST_GEOMETRY_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
&& detail::equals::equals_point_point(pt, range::front(geometry))
|| (BoundaryQuery == boundary_back || BoundaryQuery == boundary_any)
&& detail::equals::equals_point_point(pt, range::back(geometry)) );
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/de9im.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/de9im.hpp
new file mode 100644
index 0000000000..713a3fc8f0
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/de9im.hpp
@@ -0,0 +1,439 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_RELATE_DE9IM_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
+
+#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/vector_c.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/core/topological_dimension.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+// TEMP - move this header to geometry/detail
+#include <boost/geometry/index/detail/tuples.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace de9im
+{
+
+/*!
+\brief DE-9IM model intersection matrix.
+\ingroup de9im
+\details This matrix can be used to express spatial relations as defined in
+ Dimensionally Extended 9-Intersection Model.
+
+\qbk{[heading See also]}
+\qbk{* [link geometry.reference.algorithms.relation relation]}
+ */
+class matrix
+ : public detail::relate::matrix<3, 3>
+{
+#ifdef DOXYGEN_INVOKED
+public:
+ /*!
+ \brief Initializes all of the matrix elements to F
+ */
+ matrix();
+ /*!
+ \brief Subscript operator
+ \param index The index of the element
+ \return The element
+ */
+ char operator[](std::size_t index) const;
+ /*!
+ \brief Returns the iterator to the first element
+ \return const RandomAccessIterator
+ */
+ const_iterator begin() const;
+ /*!
+ \brief Returns the iterator past the last element
+ \return const RandomAccessIterator
+ */
+ const_iterator end() const;
+ /*!
+ \brief Returns the number of elements
+ \return 9
+ */
+ static std::size_t size();
+ /*!
+ \brief Returns raw pointer to elements
+ \return const pointer to array of elements
+ */
+ inline const char * data() const;
+ /*!
+ \brief Returns std::string containing elements
+ \return string containing elements
+ */
+ inline std::string str() const;
+#endif
+};
+
+/*!
+\brief DE-9IM model intersection mask.
+\ingroup de9im
+\details This mask can be used to check spatial relations as defined in
+ Dimensionally Extended 9-Intersection Model.
+
+\qbk{[heading See also]}
+\qbk{* [link geometry.reference.algorithms.relate relate]}
+ */
+class mask
+ : public detail::relate::mask<3, 3>
+{
+ typedef detail::relate::mask<3, 3> base_type;
+
+public:
+ /*!
+ \brief The constructor.
+ \param code The mask pattern.
+ */
+ inline explicit mask(const char* code)
+ : base_type(code)
+ {}
+
+ /*!
+ \brief The constructor.
+ \param code The mask pattern.
+ */
+ inline explicit mask(std::string const& code)
+ : base_type(code.c_str(), code.size())
+ {}
+};
+
+// static_mask
+
+/*!
+\brief DE-9IM model intersection mask (static version).
+\ingroup de9im
+\details This mask can be used to check spatial relations as defined in
+ Dimensionally Extended 9-Intersection Model.
+\tparam II Interior/Interior intersection mask element
+\tparam IB Interior/Boundary intersection mask element
+\tparam IE Interior/Exterior intersection mask element
+\tparam BI Boundary/Interior intersection mask element
+\tparam BB Boundary/Boundary intersection mask element
+\tparam BE Boundary/Exterior intersection mask element
+\tparam EI Exterior/Interior intersection mask element
+\tparam EB Exterior/Boundary intersection mask element
+\tparam EE Exterior/Exterior intersection mask element
+
+\qbk{[heading See also]}
+\qbk{* [link geometry.reference.algorithms.relate relate]}
+ */
+template
+<
+ char II = '*', char IB = '*', char IE = '*',
+ char BI = '*', char BB = '*', char BE = '*',
+ char EI = '*', char EB = '*', char EE = '*'
+>
+class static_mask
+ : public detail::relate::static_mask
+ <
+ boost::mpl::vector_c
+ <
+ char, II, IB, IE, BI, BB, BE, EI, EB, EE
+ >,
+ 3, 3
+ >
+{};
+
+} // namespace de9im
+
+namespace detail { namespace de9im
+{
+
+// a small helper util for ORing static masks
+
+template
+<
+ typename Seq,
+ typename T,
+ bool IsSeq = boost::mpl::is_sequence<Seq>::value
+>
+struct push_back
+{
+ typedef typename boost::mpl::push_back
+ <
+ Seq,
+ T
+ >::type type;
+};
+
+template <typename Seq, typename T>
+struct push_back<Seq, T, false>
+{};
+
+}} // namespace detail::de9im
+
+namespace de9im
+{
+
+inline
+boost::tuples::cons
+ <
+ mask,
+ boost::tuples::cons<mask, boost::tuples::null_type>
+ >
+operator||(mask const& m1, mask const& m2)
+{
+ namespace bt = boost::tuples;
+
+ return bt::cons<mask, bt::cons<mask, bt::null_type> >
+ ( m1, bt::cons<mask, bt::null_type>(m2, bt::null_type()) );
+}
+
+template <typename Tail>
+inline
+typename index::detail::tuples::push_back
+ <
+ boost::tuples::cons<mask, Tail>,
+ mask
+ >::type
+operator||(boost::tuples::cons<mask, Tail> const& t, mask const& m)
+{
+ namespace bt = boost::tuples;
+
+ return index::detail::tuples::push_back
+ <
+ bt::cons<mask, Tail>,
+ mask
+ >::apply(t, m);
+}
+
+template
+<
+ char II1, char IB1, char IE1,
+ char BI1, char BB1, char BE1,
+ char EI1, char EB1, char EE1,
+ char II2, char IB2, char IE2,
+ char BI2, char BB2, char BE2,
+ char EI2, char EB2, char EE2
+>
+inline
+boost::mpl::vector<
+ static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
+ static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
+>
+operator||(static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1> const& ,
+ static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2> const& )
+{
+ return boost::mpl::vector
+ <
+ static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
+ static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
+ >();
+}
+
+template
+<
+ typename Seq,
+ char II, char IB, char IE,
+ char BI, char BB, char BE,
+ char EI, char EB, char EE
+>
+inline
+typename detail::de9im::push_back
+ <
+ Seq,
+ static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
+ >::type
+operator||(Seq const& ,
+ static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE> const& )
+{
+ return typename detail::de9im::push_back
+ <
+ Seq,
+ static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
+ >::type();
+}
+
+} // namespace de9im
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace de9im
+{
+
+// PREDEFINED MASKS
+
+// TODO:
+// 1. specialize for simplified masks if available
+// e.g. for TOUCHES use 1 mask for A/A
+// 2. Think about dimensions > 2 e.g. should TOUCHES be true
+// if the interior of the Areal overlaps the boundary of the Volumetric
+// like it's true for Linear/Areal
+
+// EQUALS
+template <typename Geometry1, typename Geometry2>
+struct static_mask_equals_type
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
+ //typedef geometry::de9im::static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
+};
+
+// DISJOINT
+template <typename Geometry1, typename Geometry2>
+struct static_mask_disjoint_type
+{
+ typedef geometry::de9im::static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> type;
+};
+
+// TOUCHES - NOT P/P
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
+ std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
+>
+struct static_mask_touches_impl
+{
+ typedef boost::mpl::vector
+ <
+ geometry::de9im::static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
+ geometry::de9im::static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
+ geometry::de9im::static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
+ > type;
+};
+// According to OGC, doesn't apply to P/P
+// Using the above mask the result would be always false
+template <typename Geometry1, typename Geometry2>
+struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
+ : not_implemented<typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type>
+{};
+
+template <typename Geometry1, typename Geometry2>
+struct static_mask_touches_type
+ : static_mask_touches_impl<Geometry1, Geometry2>
+{};
+
+// WITHIN
+template <typename Geometry1, typename Geometry2>
+struct static_mask_within_type
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> type;
+};
+
+// COVERED_BY (non OGC)
+template <typename Geometry1, typename Geometry2>
+struct static_mask_covered_by_type
+{
+ typedef boost::mpl::vector
+ <
+ geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
+ geometry::de9im::static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
+ geometry::de9im::static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
+ geometry::de9im::static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
+ > type;
+};
+
+// CROSSES
+// dim(G1) < dim(G2) - P/L P/A L/A
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
+ std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value,
+ bool D1LessD2 = (Dim1 < Dim2)
+>
+struct static_mask_crosses_impl
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
+};
+// TODO: I'm not sure if this one below should be available!
+// dim(G1) > dim(G2) - L/P A/P A/L
+template
+<
+ typename Geometry1, typename Geometry2, std::size_t Dim1, std::size_t Dim2
+>
+struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
+{
+ typedef geometry::de9im::static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
+};
+// dim(G1) == dim(G2) - P/P A/A
+template
+<
+ typename Geometry1, typename Geometry2, std::size_t Dim
+>
+struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
+ : not_implemented
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type
+ >
+{};
+// dim(G1) == 1 && dim(G2) == 1 - L/L
+template <typename Geometry1, typename Geometry2>
+struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
+{
+ typedef geometry::de9im::static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
+};
+
+template <typename Geometry1, typename Geometry2>
+struct static_mask_crosses_type
+ : static_mask_crosses_impl<Geometry1, Geometry2>
+{};
+
+// OVERLAPS
+
+// dim(G1) != dim(G2) - NOT P/P, L/L, A/A
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
+ std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
+>
+struct static_mask_overlaps_impl
+ : not_implemented
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type
+ >
+{};
+// dim(G1) == D && dim(G2) == D - P/P A/A
+template <typename Geometry1, typename Geometry2, std::size_t Dim>
+struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
+};
+// dim(G1) == 1 && dim(G2) == 1 - L/L
+template <typename Geometry1, typename Geometry2>
+struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
+{
+ typedef geometry::de9im::static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
+};
+
+template <typename Geometry1, typename Geometry2>
+struct static_mask_overlaps_type
+ : static_mask_overlaps_impl<Geometry1, Geometry2>
+{};
+
+}} // namespace detail::de9im
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/follow_helpers.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
index 78fa03798d..ce97879fc7 100644
--- a/3party/boost/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
@@ -14,6 +14,9 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_FOLLOW_HELPERS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_FOLLOW_HELPERS_HPP
+#include <boost/geometry/core/assert.hpp>
+
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
//#include <boost/geometry/algorithms/detail/sub_range.hpp>
@@ -88,7 +91,7 @@ struct for_each_disjoint_geometry_if<OpId, Geometry, Tag, true>
Geometry const& geometry,
Pred & pred)
{
- BOOST_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(first != last);
const std::size_t count = boost::size(geometry);
boost::ignore_unused_variable_warning(count);
@@ -98,10 +101,10 @@ struct for_each_disjoint_geometry_if<OpId, Geometry, Tag, true>
std::vector<bool> detected_intersections(count, false);
for ( TurnIt it = first ; it != last ; ++it )
{
- int multi_index = it->operations[OpId].seg_id.multi_index;
- BOOST_ASSERT(multi_index >= 0);
- std::size_t index = static_cast<std::size_t>(multi_index);
- BOOST_ASSERT(index < count);
+ signed_index_type multi_index = it->operations[OpId].seg_id.multi_index;
+ BOOST_GEOMETRY_ASSERT(multi_index >= 0);
+ std::size_t const index = static_cast<std::size_t>(multi_index);
+ BOOST_GEOMETRY_ASSERT(index < count);
detected_intersections[index] = true;
}
@@ -116,8 +119,8 @@ struct for_each_disjoint_geometry_if<OpId, Geometry, Tag, true>
if ( *it == false )
{
found = true;
- bool cont = pred(range::at(geometry,
- std::distance(detected_intersections.begin(), it)));
+ std::size_t const index = std::size_t(std::distance(detected_intersections.begin(), it));
+ bool cont = pred(range::at(geometry, index));
if ( !cont )
break;
}
@@ -140,12 +143,12 @@ public:
{}
segment_identifier const& seg_id() const
{
- BOOST_ASSERT(sid_ptr);
+ BOOST_GEOMETRY_ASSERT(sid_ptr);
return *sid_ptr;
}
Point const& point() const
{
- BOOST_ASSERT(pt_ptr);
+ BOOST_GEOMETRY_ASSERT(pt_ptr);
return *pt_ptr;
}
@@ -299,15 +302,15 @@ public:
point_type const& get_exit_point() const
{
- BOOST_ASSERT(m_exit_operation != overlay::operation_none);
- BOOST_ASSERT(m_exit_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(m_exit_operation != overlay::operation_none);
+ BOOST_GEOMETRY_ASSERT(m_exit_turn_ptr);
return m_exit_turn_ptr->point;
}
TurnInfo const& get_exit_turn() const
{
- BOOST_ASSERT(m_exit_operation != overlay::operation_none);
- BOOST_ASSERT(m_exit_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(m_exit_operation != overlay::operation_none);
+ BOOST_GEOMETRY_ASSERT(m_exit_turn_ptr);
return *m_exit_turn_ptr;
}
@@ -375,14 +378,14 @@ static inline bool is_ip_on_boundary(IntersectionPoint const& ip,
bool res = false;
// IP on the last point of the linestring
- if ( (BoundaryQuery == boundary_back || BoundaryQuery == boundary_any)
+ if ( BOOST_GEOMETRY_CONDITION(BoundaryQuery == boundary_back || BoundaryQuery == boundary_any)
&& operation_info.position == overlay::position_back )
{
// check if this point is a boundary
res = boundary_checker.template is_endpoint_boundary<boundary_back>(ip);
}
// IP on the last point of the linestring
- else if ( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
+ else if ( BOOST_GEOMETRY_CONDITION(BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
&& operation_info.position == overlay::position_front )
{
// check if this point is a boundary
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/implementation.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/implementation.hpp
new file mode 100644
index 0000000000..a6f1545ed1
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/implementation.hpp
@@ -0,0 +1,110 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_RELATE_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_IMPLEMENTATION_HPP
+
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/point_point.hpp>
+#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/relate/linear_linear.hpp>
+#include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
+#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
+
+
+namespace boost { namespace geometry {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Point1, typename Point2>
+struct relate<Point1, Point2, point_tag, point_tag, 0, 0, false>
+ : detail::relate::point_point<Point1, Point2>
+{};
+
+template <typename Point, typename MultiPoint>
+struct relate<Point, MultiPoint, point_tag, multi_point_tag, 0, 0, false>
+ : detail::relate::point_multipoint<Point, MultiPoint>
+{};
+
+template <typename MultiPoint, typename Point>
+struct relate<MultiPoint, Point, multi_point_tag, point_tag, 0, 0, false>
+ : detail::relate::multipoint_point<MultiPoint, Point>
+{};
+
+template <typename MultiPoint1, typename MultiPoint2>
+struct relate<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, 0, 0, false>
+ : detail::relate::multipoint_multipoint<MultiPoint1, MultiPoint2>
+{};
+
+// TODO - for now commented out because before implementing it we must consider:
+// 1. how the Box degenerated to a Point should be treated
+// 2. what should be the definition of a Box degenerated to a Point
+// 3. what fields should the matrix/mask contain for dimension > 2 and dimension > 9
+//
+//template <typename Point, typename Box, int TopDim2>
+//struct relate<Point, Box, point_tag, box_tag, 0, TopDim2, false>
+// : detail::relate::point_box<Point, Box>
+//{};
+//
+//template <typename Box, typename Point, int TopDim1>
+//struct relate<Box, Point, box_tag, point_tag, TopDim1, 0, false>
+// : detail::relate::box_point<Box, Point>
+//{};
+
+
+template <typename Point, typename Geometry, typename Tag2, int TopDim2>
+struct relate<Point, Geometry, point_tag, Tag2, 0, TopDim2, true>
+ : detail::relate::point_geometry<Point, Geometry>
+{};
+
+template <typename Geometry, typename Point, typename Tag1, int TopDim1>
+struct relate<Geometry, Point, Tag1, point_tag, TopDim1, 0, true>
+ : detail::relate::geometry_point<Geometry, Point>
+{};
+
+
+template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
+struct relate<Linear1, Linear2, Tag1, Tag2, 1, 1, true>
+ : detail::relate::linear_linear<Linear1, Linear2>
+{};
+
+
+template <typename Linear, typename Areal, typename Tag1, typename Tag2>
+struct relate<Linear, Areal, Tag1, Tag2, 1, 2, true>
+ : detail::relate::linear_areal<Linear, Areal>
+{};
+
+template <typename Areal, typename Linear, typename Tag1, typename Tag2>
+struct relate<Areal, Linear, Tag1, Tag2, 2, 1, true>
+ : detail::relate::areal_linear<Areal, Linear>
+{};
+
+
+template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
+struct relate<Areal1, Areal2, Tag1, Tag2, 2, 2, true>
+ : detail::relate::areal_areal<Areal1, Areal2>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_IMPLEMENTATION_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/interface.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/interface.hpp
new file mode 100644
index 0000000000..e2c067b68d
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/interface.hpp
@@ -0,0 +1,348 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_RELATE_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
+
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/topological_dimension.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/de9im.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+
+
+namespace boost { namespace geometry {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate {
+
+// Those are used only to allow dispatch::relate to produce compile-time error
+
+template <typename Geometry,
+ typename Tag = typename geometry::tag<Geometry>::type>
+struct is_supported_by_generic
+{
+ static const bool value
+ = boost::is_same<Tag, linestring_tag>::value
+ || boost::is_same<Tag, multi_linestring_tag>::value
+ || boost::is_same<Tag, ring_tag>::value
+ || boost::is_same<Tag, polygon_tag>::value
+ || boost::is_same<Tag, multi_polygon_tag>::value;
+};
+
+template <typename Geometry1,
+ typename Geometry2,
+ typename Tag1 = typename geometry::tag<Geometry1>::type,
+ typename Tag2 = typename geometry::tag<Geometry2>::type>
+struct is_generic
+{
+ static const bool value = is_supported_by_generic<Geometry1>::value
+ && is_supported_by_generic<Geometry2>::value;
+};
+
+
+template <typename Point, typename Geometry, typename Tag>
+struct is_generic<Point, Geometry, point_tag, Tag>
+{
+ static const bool value = is_supported_by_generic<Geometry>::value;
+};
+
+template <typename Geometry, typename Point, typename Tag>
+struct is_generic<Geometry, Point, Tag, point_tag>
+{
+ static const bool value = is_supported_by_generic<Geometry>::value;
+};
+
+template <typename Point1, typename Point2>
+struct is_generic<Point1, Point2, point_tag, point_tag>
+{
+ static const bool value = false;
+};
+
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template <typename Geometry1,
+ typename Geometry2,
+ typename Tag1 = typename geometry::tag<Geometry1>::type,
+ typename Tag2 = typename geometry::tag<Geometry2>::type,
+ int TopDim1 = geometry::topological_dimension<Geometry1>::value,
+ int TopDim2 = geometry::topological_dimension<Geometry2>::value,
+ bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
+>
+struct relate : not_implemented<Tag1, Tag2>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate {
+
+template <typename Geometry1, typename Geometry2>
+struct interruption_enabled
+{
+ static const bool value =
+ dispatch::relate<Geometry1, Geometry2>::interruption_enabled;
+};
+
+template <typename Geometry1,
+ typename Geometry2,
+ typename Result,
+ bool IsSequence = boost::mpl::is_sequence<Result>::value>
+struct result_handler_type
+ : not_implemented<Result>
+{};
+
+template <typename Geometry1, typename Geometry2>
+struct result_handler_type<Geometry1, Geometry2, geometry::de9im::mask, false>
+{
+ typedef mask_handler
+ <
+ geometry::de9im::mask,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+template <typename Geometry1, typename Geometry2, typename Head, typename Tail>
+struct result_handler_type<Geometry1, Geometry2, boost::tuples::cons<Head, Tail>, false>
+{
+ typedef mask_handler
+ <
+ boost::tuples::cons<Head, Tail>,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+template <typename Geometry1, typename Geometry2,
+ char II, char IB, char IE,
+ char BI, char BB, char BE,
+ char EI, char EB, char EE>
+struct result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
+ false
+ >
+{
+ typedef static_mask_handler
+ <
+ geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+template <typename Geometry1, typename Geometry2, typename StaticSequence>
+struct result_handler_type<Geometry1, Geometry2, StaticSequence, true>
+{
+ typedef static_mask_handler
+ <
+ StaticSequence,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+namespace resolve_variant {
+
+template <typename Geometry1, typename Geometry2>
+struct relate
+{
+ template <typename Mask>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Mask const& mask)
+ {
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ typename detail::relate::result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ Mask
+ >::type handler(mask);
+
+ dispatch::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, handler);
+
+ return handler.result();
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct relate<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename Mask>
+ struct visitor : boost::static_visitor<bool>
+ {
+ Geometry2 const& m_geometry2;
+ Mask const& m_mask;
+
+ visitor(Geometry2 const& geometry2, Mask const& mask)
+ : m_geometry2(geometry2), m_mask(mask) {}
+
+ template <typename Geometry1>
+ bool operator()(Geometry1 const& geometry1) const
+ {
+ return relate<Geometry1, Geometry2>
+ ::apply(geometry1, m_geometry2, m_mask);
+ }
+ };
+
+ template <typename Mask>
+ static inline bool
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ Mask const& mask)
+ {
+ return boost::apply_visitor(visitor<Mask>(geometry2, mask), geometry1);
+ }
+};
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct relate<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Mask>
+ struct visitor : boost::static_visitor<bool>
+ {
+ Geometry1 const& m_geometry1;
+ Mask const& m_mask;
+
+ visitor(Geometry1 const& geometry1, Mask const& mask)
+ : m_geometry1(geometry1), m_mask(mask) {}
+
+ template <typename Geometry2>
+ bool operator()(Geometry2 const& geometry2) const
+ {
+ return relate<Geometry1, Geometry2>
+ ::apply(m_geometry1, geometry2, m_mask);
+ }
+ };
+
+ template <typename Mask>
+ static inline bool
+ apply(Geometry1 const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Mask const& mask)
+ {
+ return boost::apply_visitor(visitor<Mask>(geometry1, mask), geometry2);
+ }
+};
+
+template <
+ BOOST_VARIANT_ENUM_PARAMS(typename T1),
+ BOOST_VARIANT_ENUM_PARAMS(typename T2)
+>
+struct relate<
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
+>
+{
+ template <typename Mask>
+ struct visitor : boost::static_visitor<bool>
+ {
+ Mask const& m_mask;
+
+ visitor(Mask const& mask)
+ : m_mask(mask) {}
+
+ template <typename Geometry1, typename Geometry2>
+ bool operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ return relate<Geometry1, Geometry2>
+ ::apply(geometry1, geometry2, m_mask);
+ }
+ };
+
+ template <typename Mask>
+ static inline bool
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
+ Mask const& mask)
+ {
+ return boost::apply_visitor(visitor<Mask>(mask), geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
+
+/*!
+\brief Checks relation between a pair of geometries defined by a mask.
+\ingroup relate
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Mask An intersection model Mask type.
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param mask An intersection model mask object.
+\return true if the relation is compatible with the mask, false otherwise.
+
+\qbk{[include reference/algorithms/relate.qbk]}
+ */
+template <typename Geometry1, typename Geometry2, typename Mask>
+inline bool relate(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Mask const& mask)
+{
+ return resolve_variant::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, mask);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/less.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/less.hpp
index 3f11d4e87d..462fcc35f1 100644
--- a/3party/boost/boost/geometry/algorithms/detail/relate/less.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/less.hpp
@@ -14,6 +14,10 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LESS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LESS_HPP
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/util/math.hpp>
+
namespace boost { namespace geometry
{
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/linear_areal.hpp
index f05832d552..a1d5f0adbc 100644
--- a/3party/boost/boost/geometry/algorithms/detail/relate/linear_areal.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/linear_areal.hpp
@@ -2,19 +2,25 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_AREAL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_AREAL_HPP
+#include <boost/core/ignore_unused.hpp>
+#include <boost/range/size.hpp>
+
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/topological_dimension.hpp>
+
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
@@ -93,7 +99,7 @@ public:
}
int const pig = detail::within::point_in_geometry(range::front(linestring), m_geometry2);
- //BOOST_ASSERT_MSG(pig != 0, "There should be no IPs");
+ //BOOST_GEOMETRY_ASSERT_MSG(pig != 0, "There should be no IPs");
if ( pig > 0 )
{
@@ -191,6 +197,33 @@ struct linear_areal
typedef typename geometry::point_type<Geometry1>::type point1_type;
typedef typename geometry::point_type<Geometry2>::type point2_type;
+
+ template <typename Geometry>
+ struct is_multi
+ : boost::is_base_of
+ <
+ multi_tag,
+ typename tag<Geometry>::type
+ >
+ {};
+
+ template <typename Geom1, typename Geom2>
+ struct multi_turn_info
+ : turns::get_turns<Geom1, Geom2>::turn_info
+ {
+ multi_turn_info() : priority(0) {}
+ int priority; // single-geometry sorting priority
+ };
+
+ template <typename Geom1, typename Geom2>
+ struct turn_info_type
+ : boost::mpl::if_c
+ <
+ is_multi<Geometry2>::value,
+ multi_turn_info<Geom1, Geom2>,
+ typename turns::get_turns<Geom1, Geom2>::turn_info
+ >
+ {};
template <typename Result>
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
@@ -200,17 +233,17 @@ struct linear_areal
// The result should be FFFFFFFFF
relate::set<exterior, exterior, result_dimension<Geometry2>::value, TransposeResult>(result);// FFFFFFFFd, d in [1,9] or T
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
// get and analyse turns
- typedef typename turns::get_turns<Geometry1, Geometry2>::turn_info turn_type;
+ typedef typename turn_info_type<Geometry1, Geometry2>::type turn_type;
std::vector<turn_type> turns;
interrupt_policy_linear_areal<Geometry2, Result> interrupt_policy(geometry2, result);
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
boundary_checker<Geometry1> boundary_checker1(geometry1);
@@ -222,12 +255,12 @@ struct linear_areal
TransposeResult
> pred1(geometry2, result, boundary_checker1);
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
no_turns_la_areal_pred<Result, !TransposeResult> pred2(result);
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
if ( turns.empty() )
@@ -236,14 +269,11 @@ struct linear_areal
// This is set here because in the case if empty Areal geometry were passed
// those shouldn't be set
relate::set<exterior, interior, '2', TransposeResult>(result);// FFFFFF2Fd
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
{
- // for different multi or same ring id: x, u, i, c
- // for same multi and different ring id: c, i, u, x
- typedef turns::less<0, turns::less_op_linear_areal> less;
- std::sort(turns.begin(), turns.end(), less());
+ sort_dispatch(turns.begin(), turns.end(), is_multi<Geometry2>());
turns_analyser<turn_type> analyser;
analyse_each_turn(result, analyser,
@@ -251,7 +281,7 @@ struct linear_areal
geometry1, geometry2,
boundary_checker1);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
}
@@ -295,8 +325,8 @@ struct linear_areal
// if there was some previous ring
if ( prev_seg_id_ptr != NULL )
{
- int const next_ring_index = prev_seg_id_ptr->ring_index + 1;
- BOOST_ASSERT(next_ring_index >= 0);
+ signed_index_type const next_ring_index = prev_seg_id_ptr->ring_index + 1;
+ BOOST_GEOMETRY_ASSERT(next_ring_index >= 0);
// if one of the last rings of previous single geometry was ommited
if ( static_cast<std::size_t>(next_ring_index)
@@ -339,7 +369,7 @@ struct linear_areal
else
{
// u, c
- typedef turns::less<1, turns::less_op_areal_linear> less;
+ typedef turns::less<1, turns::less_op_areal_linear<1> > less;
std::sort(it, next, less());
// analyse
@@ -366,8 +396,8 @@ struct linear_areal
// if there was some previous ring
if ( prev_seg_id_ptr != NULL )
{
- int const next_ring_index = prev_seg_id_ptr->ring_index + 1;
- BOOST_ASSERT(next_ring_index >= 0);
+ signed_index_type const next_ring_index = prev_seg_id_ptr->ring_index + 1;
+ BOOST_GEOMETRY_ASSERT(next_ring_index >= 0);
// if one of the last rings of previous single geometry was ommited
if ( static_cast<std::size_t>(next_ring_index)
@@ -381,6 +411,127 @@ struct linear_areal
}
}
+ template <typename It, typename Pred, typename Comp>
+ static void for_each_equal_range(It first, It last, Pred pred, Comp comp)
+ {
+ if ( first == last )
+ return;
+
+ It first_equal = first;
+ It prev = first;
+ for ( ++first ; ; ++first, ++prev )
+ {
+ if ( first == last || !comp(*prev, *first) )
+ {
+ pred(first_equal, first);
+ first_equal = first;
+ }
+
+ if ( first == last )
+ break;
+ }
+ }
+
+ struct same_ip
+ {
+ template <typename Turn>
+ bool operator()(Turn const& left, Turn const& right) const
+ {
+ return left.operations[0].seg_id == right.operations[0].seg_id
+ && left.operations[0].fraction == right.operations[0].fraction;
+ }
+ };
+
+ struct same_ip_and_multi_index
+ {
+ template <typename Turn>
+ bool operator()(Turn const& left, Turn const& right) const
+ {
+ return same_ip()(left, right)
+ && left.operations[1].seg_id.multi_index == right.operations[1].seg_id.multi_index;
+ }
+ };
+
+ template <typename OpToPriority>
+ struct set_turns_group_priority
+ {
+ template <typename TurnIt>
+ void operator()(TurnIt first, TurnIt last) const
+ {
+ BOOST_GEOMETRY_ASSERT(first != last);
+ static OpToPriority op_to_priority;
+ // find the operation with the least priority
+ int least_priority = op_to_priority(first->operations[0]);
+ for ( TurnIt it = first + 1 ; it != last ; ++it )
+ {
+ int priority = op_to_priority(it->operations[0]);
+ if ( priority < least_priority )
+ least_priority = priority;
+ }
+ // set the least priority for all turns of the group
+ for ( TurnIt it = first ; it != last ; ++it )
+ {
+ it->priority = least_priority;
+ }
+ }
+ };
+
+ template <typename SingleLess>
+ struct sort_turns_group
+ {
+ struct less
+ {
+ template <typename Turn>
+ bool operator()(Turn const& left, Turn const& right) const
+ {
+ return left.operations[1].seg_id.multi_index == right.operations[1].seg_id.multi_index ?
+ SingleLess()(left, right) :
+ left.priority < right.priority;
+ }
+ };
+
+ template <typename TurnIt>
+ void operator()(TurnIt first, TurnIt last) const
+ {
+ std::sort(first, last, less());
+ }
+ };
+
+ template <typename TurnIt>
+ static void sort_dispatch(TurnIt first, TurnIt last, boost::true_type const& /*is_multi*/)
+ {
+ // sort turns by Linear seg_id, then by fraction, then by other multi_index
+ typedef turns::less<0, turns::less_other_multi_index<0> > less;
+ std::sort(first, last, less());
+
+ // For the same IP and multi_index - the same other's single geometry
+ // set priorities as the least operation found for the whole single geometry
+ // so e.g. single geometries containing 'u' will always be before those only containing 'i'
+ typedef turns::op_to_int<0,2,3,1,4,0> op_to_int_xuic;
+ for_each_equal_range(first, last,
+ set_turns_group_priority<op_to_int_xuic>(), // least operation in xuic order
+ same_ip_and_multi_index()); // other's multi_index
+
+ // When priorities for single geometries are set now sort turns for the same IP
+ // if multi_index is the same sort them according to the single-less
+ // else use priority of the whole single-geometry set earlier
+ typedef turns::less<0, turns::less_op_linear_areal_single<0> > single_less;
+ for_each_equal_range(first, last,
+ sort_turns_group<single_less>(),
+ same_ip());
+ }
+
+ template <typename TurnIt>
+ static void sort_dispatch(TurnIt first, TurnIt last, boost::false_type const& /*is_multi*/)
+ {
+ // sort turns by Linear seg_id, then by fraction, then
+ // for same ring id: x, u, i, c
+ // for different ring id: c, i, u, x
+ typedef turns::less<0, turns::less_op_linear_areal_single<0> > less;
+ std::sort(first, last, less());
+ }
+
+
// interrupt policy which may be passed to get_turns to interrupt the analysis
// based on the info in the passed result/mask
template <typename Areal, typename Result>
@@ -456,6 +607,8 @@ struct linear_areal
, m_boundary_counter(0)
, m_interior_detected(false)
, m_first_interior_other_id_ptr(NULL)
+ , m_first_from_unknown(false)
+ , m_first_from_unknown_boundary_detected(false)
{}
template <typename Result,
@@ -483,6 +636,11 @@ struct linear_areal
const bool first_in_range = m_seg_watcher.update(seg_id);
+ // TODO: should apply() for the post-last ip be called if first_in_range ?
+ // this would unify how last points in ranges are handled
+ // possibly replacing parts of the code below
+ // e.g. for is_multi and m_interior_detected
+
// handle possible exit
bool fake_enter_detected = false;
if ( m_exit_watcher.get_exit_operation() == overlay::operation_union )
@@ -493,8 +651,24 @@ struct linear_areal
{
m_exit_watcher.reset_detected_exit();
- // not the last IP
update<interior, exterior, '1', TransposeResult>(res);
+
+ // next single geometry
+ if ( first_in_range && m_previous_turn_ptr )
+ {
+ // NOTE: similar code is in the post-last-ip-apply()
+ segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
+
+ bool const prev_back_b = is_endpoint_on_boundary<boundary_back>(
+ range::back(sub_range(geometry, prev_seg_id)),
+ boundary_checker);
+
+ // if there is a boundary on the last point
+ if ( prev_back_b )
+ {
+ update<boundary, exterior, '0', TransposeResult>(res);
+ }
+ }
}
// fake exit point, reset state
else if ( op == overlay::operation_intersection
@@ -506,9 +680,12 @@ struct linear_areal
}
else if ( m_exit_watcher.get_exit_operation() == overlay::operation_blocked )
{
- // ignore multiple BLOCKs
- if ( op == overlay::operation_blocked )
+ // ignore multiple BLOCKs for this same single geometry1
+ if ( op == overlay::operation_blocked
+ && seg_id.multi_index == m_previous_turn_ptr->operations[op_id].seg_id.multi_index )
+ {
return;
+ }
if ( ( op == overlay::operation_intersection
|| op == overlay::operation_continue )
@@ -520,11 +697,39 @@ struct linear_areal
m_exit_watcher.reset_detected_exit();
}
+ if ( BOOST_GEOMETRY_CONDITION( is_multi<OtherGeometry>::value )
+ && m_first_from_unknown )
+ {
+ // For MultiPolygon many x/u operations may be generated as a first IP
+ // if for all turns x/u was generated and any of the Polygons doesn't contain the LineString
+ // then we know that the LineString is outside
+ // Similar with the u/u turns, if it was the first one it doesn't mean that the
+ // Linestring came from the exterior
+ if ( ( m_previous_operation == overlay::operation_blocked
+ && ( op != overlay::operation_blocked // operation different than block
+ || seg_id.multi_index != m_previous_turn_ptr->operations[op_id].seg_id.multi_index ) ) // or the next single-geometry
+ || ( m_previous_operation == overlay::operation_union
+ && ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it) )
+ )
+ {
+ update<interior, exterior, '1', TransposeResult>(res);
+ if ( m_first_from_unknown_boundary_detected )
+ {
+ update<boundary, exterior, '0', TransposeResult>(res);
+ }
+
+ m_first_from_unknown = false;
+ m_first_from_unknown_boundary_detected = false;
+ }
+ }
+
// NOTE: THE WHOLE m_interior_detected HANDLING IS HERE BECAUSE WE CAN'T EFFICIENTLY SORT TURNS (CORRECTLY)
// BECAUSE THE SAME IP MAY BE REPRESENTED BY TWO SEGMENTS WITH DIFFERENT DISTANCES
// IT WOULD REQUIRE THE CALCULATION OF MAX DISTANCE
// TODO: WE COULD GET RID OF THE TEST IF THE DISTANCES WERE NORMALIZED
+// UPDATE: THEY SHOULD BE NORMALIZED NOW
+
// TODO: THIS IS POTENTIALLY ERROREOUS!
// THIS ALGORITHM DEPENDS ON SOME SPECIFIC SEQUENCE OF OPERATIONS
// IT WOULD GIVE WRONG RESULTS E.G.
@@ -538,6 +743,30 @@ struct linear_areal
{
update<interior, interior, '1', TransposeResult>(res);
m_interior_detected = false;
+
+ // new range detected - reset previous state and check the boundary
+ if ( first_in_range )
+ {
+ // actually it should be != NULL if m_interior_detected
+ // so an assert could be checked here
+ if ( m_previous_turn_ptr )
+ {
+ segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
+
+ bool const prev_back_b = is_endpoint_on_boundary<boundary_back>(
+ range::back(sub_range(geometry, prev_seg_id)),
+ boundary_checker);
+
+ // if there is a boundary on the last point
+ if ( prev_back_b )
+ {
+ update<boundary, interior, '0', TransposeResult>(res);
+ }
+ }
+
+ // The exit_watcher is reset below
+ // m_exit_watcher.reset();
+ }
}
// fake interior overlap
else if ( op == overlay::operation_continue )
@@ -558,10 +787,20 @@ struct linear_areal
}
}
+ // NOTE: If post-last-ip apply() was called this wouldn't be needed
+ if ( first_in_range )
+ {
+ m_exit_watcher.reset();
+ m_boundary_counter = 0;
+ m_first_from_unknown = false;
+ m_first_from_unknown_boundary_detected = false;
+ }
+
// i/u, c/u
if ( op == overlay::operation_intersection
|| op == overlay::operation_continue ) // operation_boundary/operation_boundary_intersection
{
+ bool const first_point = first_in_range || m_first_from_unknown;
bool no_enters_detected = m_exit_watcher.is_outside();
m_exit_watcher.enter(*it);
@@ -590,7 +829,7 @@ struct linear_areal
{
// don't add to the count for all met boundaries
// only if this is the "new" boundary
- if ( first_in_range || !it->operations[op_id].is_collinear )
+ if ( first_point || !it->operations[op_id].is_collinear )
++m_boundary_counter;
update<interior, boundary, '1', TransposeResult>(res);
@@ -617,7 +856,7 @@ struct linear_areal
&& it->operations[op_id].position != overlay::position_front )
{
// TODO: calculate_from_inside() is only needed if the current Linestring is not closed
- bool const from_inside = first_in_range
+ bool const from_inside = first_point
&& calculate_from_inside(geometry,
other_geometry,
*it);
@@ -628,7 +867,7 @@ struct linear_areal
update<interior, exterior, '1', TransposeResult>(res);
// if it's the first IP then the first point is outside
- if ( first_in_range )
+ if ( first_point )
{
bool const front_b = is_endpoint_on_boundary<boundary_front>(
range::front(sub_range(geometry, seg_id)),
@@ -645,6 +884,12 @@ struct linear_areal
}
}
}
+
+ if ( BOOST_GEOMETRY_CONDITION( is_multi<OtherGeometry>::value ) )
+ {
+ m_first_from_unknown = false;
+ m_first_from_unknown_boundary_detected = false;
+ }
}
// u/u, x/u
else if ( op == overlay::operation_union || op == overlay::operation_blocked )
@@ -707,7 +952,11 @@ struct linear_areal
if ( it->operations[op_id].position != overlay::position_front )
{
// TODO: calculate_from_inside() is only needed if the current Linestring is not closed
- bool const first_from_inside = first_in_range
+ // NOTE: this is not enough for MultiPolygon and operation_blocked
+ // For LS/MultiPolygon multiple x/u turns may be generated
+ // the first checked Polygon may be the one which LS is outside for.
+ bool const first_point = first_in_range || m_first_from_unknown;
+ bool const first_from_inside = first_point
&& calculate_from_inside(geometry,
other_geometry,
*it);
@@ -717,14 +966,26 @@ struct linear_areal
// notify the exit_watcher that we started inside
m_exit_watcher.enter(*it);
+ // and reset unknown flags since we know that we started inside
+ m_first_from_unknown = false;
+ m_first_from_unknown_boundary_detected = false;
}
else
{
- update<interior, exterior, '1', TransposeResult>(res);
+ if ( BOOST_GEOMETRY_CONDITION( is_multi<OtherGeometry>::value )
+ /*&& ( op == overlay::operation_blocked
+ || op == overlay::operation_union )*/ ) // if we're here it's u or x
+ {
+ m_first_from_unknown = true;
+ }
+ else
+ {
+ update<interior, exterior, '1', TransposeResult>(res);
+ }
}
// first IP on the last segment point - this means that the first point is outside or inside
- if ( first_in_range && ( !this_b || op_blocked ) )
+ if ( first_point && ( !this_b || op_blocked ) )
{
bool const front_b = is_endpoint_on_boundary<boundary_front>(
range::front(sub_range(geometry, seg_id)),
@@ -734,9 +995,23 @@ struct linear_areal
if ( front_b )
{
if ( first_from_inside )
+ {
update<boundary, interior, '0', TransposeResult>(res);
+ }
else
- update<boundary, exterior, '0', TransposeResult>(res);
+ {
+ if ( BOOST_GEOMETRY_CONDITION( is_multi<OtherGeometry>::value )
+ /*&& ( op == overlay::operation_blocked
+ || op == overlay::operation_union )*/ ) // if we're here it's u or x
+ {
+ BOOST_GEOMETRY_ASSERT(m_first_from_unknown);
+ m_first_from_unknown_boundary_detected = true;
+ }
+ else
+ {
+ update<boundary, exterior, '0', TransposeResult>(res);
+ }
+ }
}
}
}
@@ -769,7 +1044,25 @@ struct linear_areal
OtherGeometry const& /*other_geometry*/,
BoundaryChecker const& boundary_checker)
{
- //BOOST_ASSERT( first != last );
+ boost::ignore_unused(first, last);
+ //BOOST_GEOMETRY_ASSERT( first != last );
+
+ // For MultiPolygon many x/u operations may be generated as a first IP
+ // if for all turns x/u was generated and any of the Polygons doesn't contain the LineString
+ // then we know that the LineString is outside
+ if ( BOOST_GEOMETRY_CONDITION( is_multi<OtherGeometry>::value )
+ && m_first_from_unknown )
+ {
+ update<interior, exterior, '1', TransposeResult>(res);
+ if ( m_first_from_unknown_boundary_detected )
+ {
+ update<boundary, exterior, '0', TransposeResult>(res);
+ }
+
+ // done below
+ //m_first_from_unknown = false;
+ //m_first_from_unknown_boundary_detected = false;
+ }
// here, the possible exit is the real one
// we know that we entered and now we exit
@@ -780,8 +1073,8 @@ struct linear_areal
// for sure
update<interior, exterior, '1', TransposeResult>(res);
- BOOST_ASSERT(first != last);
- BOOST_ASSERT(m_previous_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr);
segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
@@ -803,8 +1096,8 @@ struct linear_areal
update<interior, interior, '1', TransposeResult>(res);
m_interior_detected = false;
- BOOST_ASSERT(first != last);
- BOOST_ASSERT(m_previous_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr);
segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
@@ -819,12 +1112,37 @@ struct linear_areal
}
}
- BOOST_ASSERT_MSG(m_previous_operation != overlay::operation_continue,
- "Unexpected operation! Probably the error in get_turns(L,A) or relate(L,A)");
+ // This condition may be false if the Linestring is lying on the Polygon's collinear spike
+ // if Polygon's spikes are not handled in get_turns() or relate() (they currently aren't)
+ //BOOST_GEOMETRY_ASSERT_MSG(m_previous_operation != overlay::operation_continue,
+ // "Unexpected operation! Probably the error in get_turns(L,A) or relate(L,A)");
+ // Currently one c/c turn is generated for the exit
+ // when a Linestring is going out on a collinear spike
+ // When a Linestring is going in on a collinear spike
+ // the turn is not generated for the entry
+ // So assume it's the former
+ if ( m_previous_operation == overlay::operation_continue )
+ {
+ update<interior, exterior, '1', TransposeResult>(res);
+
+ segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
+
+ bool const prev_back_b = is_endpoint_on_boundary<boundary_back>(
+ range::back(sub_range(geometry, prev_seg_id)),
+ boundary_checker);
+
+ // if there is a boundary on the last point
+ if ( prev_back_b )
+ {
+ update<boundary, exterior, '0', TransposeResult>(res);
+ }
+ }
// Reset exit watcher before the analysis of the next Linestring
m_exit_watcher.reset();
m_boundary_counter = 0;
+ m_first_from_unknown = false;
+ m_first_from_unknown_boundary_detected = false;
}
// check if the passed turn's segment of Linear geometry arrived
@@ -844,15 +1162,16 @@ struct linear_areal
typedef typename boost::range_iterator<range2_type>::type range2_iterator;
range2_type range2(sub_range(geometry2, turn.operations[other_op_id].seg_id));
- std::size_t const s1 = boost::size(range1);
+ BOOST_GEOMETRY_ASSERT(boost::size(range1));
std::size_t const s2 = boost::size(range2);
- BOOST_ASSERT(s1 > 1 && s2 > 2);
+ BOOST_GEOMETRY_ASSERT(s2 > 2);
std::size_t const seg_count2 = s2 - 1;
- std::size_t const p_seg_ij = turn.operations[op_id].seg_id.segment_index;
- std::size_t const q_seg_ij = turn.operations[other_op_id].seg_id.segment_index;
+ std::size_t const p_seg_ij = static_cast<std::size_t>(turn.operations[op_id].seg_id.segment_index);
+ std::size_t const q_seg_ij = static_cast<std::size_t>(turn.operations[other_op_id].seg_id.segment_index);
- BOOST_ASSERT(p_seg_ij + 1 < s1 && q_seg_ij + 1 < s2);
+ BOOST_GEOMETRY_ASSERT(p_seg_ij + 1 < boost::size(range1));
+ BOOST_GEOMETRY_ASSERT(q_seg_ij + 1 < s2);
point1_type const& pi = range::at(range1, p_seg_ij);
point2_type const& qi = range::at(range2, q_seg_ij);
@@ -861,8 +1180,8 @@ struct linear_areal
geometry::convert(qi, qi_conv);
bool const is_ip_qj = equals::equals_point_point(turn.point, qj);
// TODO: test this!
-// BOOST_ASSERT(!equals::equals_point_point(turn.point, pi));
-// BOOST_ASSERT(!equals::equals_point_point(turn.point, qi));
+// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, pi));
+// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, qi));
point1_type new_pj;
geometry::convert(turn.point, new_pj);
@@ -872,7 +1191,7 @@ struct linear_areal
// TODO: the following function should return immediately, however the worst case complexity is O(N)
// It would be good to replace it with some O(1) mechanism
range2_iterator qk_it = find_next_non_duplicated(boost::begin(range2),
- boost::begin(range2) + q_seg_jk,
+ range::pos(range2, q_seg_jk),
boost::end(range2));
// Will this sequence of points be always correct?
@@ -894,7 +1213,7 @@ struct linear_areal
template <typename It>
static inline It find_next_non_duplicated(It first, It current, It last)
{
- BOOST_ASSERT( current != last );
+ BOOST_GEOMETRY_ASSERT( current != last );
It it = current;
@@ -941,6 +1260,8 @@ struct linear_areal
unsigned m_boundary_counter;
bool m_interior_detected;
const segment_identifier * m_first_interior_other_id_ptr;
+ bool m_first_from_unknown;
+ bool m_first_from_unknown_boundary_detected;
};
// call analyser.apply() for each turn in range
@@ -967,7 +1288,7 @@ struct linear_areal
geometry, other_geometry,
boundary_checker);
- if ( res.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( res.interrupt ) )
return;
}
@@ -1013,8 +1334,8 @@ struct linear_areal
if ( first == last )
return last;
- int const multi_index = first->operations[1].seg_id.multi_index;
- int const ring_index = first->operations[1].seg_id.ring_index;
+ signed_index_type const multi_index = first->operations[1].seg_id.multi_index;
+ signed_index_type const ring_index = first->operations[1].seg_id.ring_index;
fun(*first);
++first;
@@ -1060,7 +1381,7 @@ struct linear_areal
if ( is_union_detected )
{
- BOOST_ASSERT(m_previous_turn_ptr != NULL);
+ BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr != NULL);
if ( !detail::equals::equals_point_point(it->point, m_previous_turn_ptr->point) )
{
// break
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/linear_linear.hpp
index f08aba0287..7a3f373e03 100644
--- a/3party/boost/boost/geometry/algorithms/detail/relate/linear_linear.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/linear_linear.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -14,12 +14,21 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
+#include <algorithm>
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/range/size.hpp>
+
+#include <boost/geometry/core/assert.hpp>
+
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/detail/sub_range.hpp>
#include <boost/geometry/algorithms/detail/single_geometry.hpp>
#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
#include <boost/geometry/algorithms/detail/relate/boundary_checker.hpp>
#include <boost/geometry/algorithms/detail/relate/follow_helpers.hpp>
@@ -115,7 +124,7 @@ struct linear_linear
{
// The result should be FFFFFFFFF
relate::set<exterior, exterior, result_dimension<Geometry1>::value>(result);// FFFFFFFFd, d in [1,9] or T
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
// get and analyse turns
@@ -131,19 +140,19 @@ struct linear_linear
detail::get_turns::get_turn_info_type<Geometry1, Geometry2, turns::assign_policy<true> >
>::apply(turns, geometry1, geometry2, interrupt_policy);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
boundary_checker<Geometry1> boundary_checker1(geometry1);
disjoint_linestring_pred<Result, boundary_checker<Geometry1>, false> pred1(result, boundary_checker1);
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
boundary_checker<Geometry2> boundary_checker2(geometry2);
disjoint_linestring_pred<Result, boundary_checker<Geometry2>, true> pred2(result, boundary_checker2);
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
if ( turns.empty() )
@@ -159,7 +168,7 @@ struct linear_linear
|| may_update<boundary, boundary, '0'>(result)
|| may_update<boundary, exterior, '0'>(result) )
{
- typedef turns::less<0, turns::less_op_linear_linear> less;
+ typedef turns::less<0, turns::less_op_linear_linear<0> > less;
std::sort(turns.begin(), turns.end(), less());
turns_analyser<turn_type, 0> analyser;
@@ -169,7 +178,7 @@ struct linear_linear
boundary_checker1, boundary_checker2);
}
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
if ( may_update<interior, interior, '1', true>(result)
@@ -179,7 +188,7 @@ struct linear_linear
|| may_update<boundary, boundary, '0', true>(result)
|| may_update<boundary, exterior, '0', true>(result) )
{
- typedef turns::less<1, turns::less_op_linear_linear> less;
+ typedef turns::less<1, turns::less_op_linear_linear<1> > less;
std::sort(turns.begin(), turns.end(), less());
turns_analyser<turn_type, 1> analyser;
@@ -248,6 +257,7 @@ struct linear_linear
: m_previous_turn_ptr(NULL)
, m_previous_operation(overlay::operation_none)
, m_degenerated_turn_ptr(NULL)
+ , m_collinear_spike_exit(false)
{}
template <typename Result,
@@ -381,7 +391,8 @@ struct linear_linear
// if we didn't enter in the past, we were outside
if ( was_outside
&& ! fake_enter_detected
- && it->operations[op_id].position != overlay::position_front )
+ && it->operations[op_id].position != overlay::position_front
+ && ! m_collinear_spike_exit )
{
update<interior, exterior, '1', transpose_result>(res);
@@ -400,6 +411,8 @@ struct linear_linear
}
}
}
+
+ m_collinear_spike_exit = false;
}
// u/i, u/u, u/x, x/i, x/u, x/x
else if ( op == overlay::operation_union || op == overlay::operation_blocked )
@@ -416,6 +429,11 @@ struct linear_linear
if ( !was_outside && is_collinear )
{
m_exit_watcher.exit(*it, false);
+ // if the position is not set to back it must be a spike
+ if ( it->operations[op_id].position != overlay::position_back )
+ {
+ m_collinear_spike_exit = true;
+ }
}
bool const op_blocked = op == overlay::operation_blocked;
@@ -454,6 +472,7 @@ struct linear_linear
// if we are truly outside
if ( was_outside
&& it->operations[op_id].position != overlay::position_front
+ && ! m_collinear_spike_exit
/*&& !is_collinear*/ )
{
update<interior, exterior, '1', transpose_result>(res);
@@ -524,6 +543,7 @@ struct linear_linear
&& ( !this_b || op_blocked )
&& was_outside
&& it->operations[op_id].position != overlay::position_front
+ && ! m_collinear_spike_exit
/*&& !is_collinear*/ )
{
bool const front_b = is_endpoint_on_boundary<boundary_front>(
@@ -561,7 +581,8 @@ struct linear_linear
BoundaryChecker const& boundary_checker,
OtherBoundaryChecker const& /*other_boundary_checker*/)
{
- //BOOST_ASSERT( first != last );
+ boost::ignore_unused(first, last);
+ //BOOST_GEOMETRY_ASSERT( first != last );
// here, the possible exit is the real one
// we know that we entered and now we exit
@@ -571,7 +592,7 @@ struct linear_linear
{
update<interior, exterior, '1', transpose_result>(res);
- BOOST_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(first != last);
const TurnInfo * turn_ptr = NULL;
if ( m_degenerated_turn_ptr )
@@ -583,7 +604,7 @@ struct linear_linear
{
segment_identifier const& prev_seg_id = turn_ptr->operations[op_id].seg_id;
- //BOOST_ASSERT(!boost::empty(sub_range(geometry, prev_seg_id)));
+ //BOOST_GEOMETRY_ASSERT(!boost::empty(sub_range(geometry, prev_seg_id)));
bool const prev_back_b = is_endpoint_on_boundary<boundary_back>(
range::back(sub_range(geometry, prev_seg_id)),
boundary_checker);
@@ -604,6 +625,10 @@ struct linear_linear
m_previous_turn_ptr = NULL;
m_previous_operation = overlay::operation_none;
m_degenerated_turn_ptr = NULL;
+
+ // actually if this is set to true here there is some error
+ // in get_turns_ll or relate_ll, an assert could be checked here
+ m_collinear_spike_exit = false;
}
template <typename Result,
@@ -623,7 +648,7 @@ struct linear_linear
typename detail::single_geometry_return_type<Geometry const>::type
ls1_ref = detail::single_geometry(geometry, turn.operations[op_id].seg_id);
typename detail::single_geometry_return_type<OtherGeometry const>::type
- ls2_ref = detail::single_geometry(other_geometry, turn.operations[op_id].other_id);
+ ls2_ref = detail::single_geometry(other_geometry, turn.operations[other_op_id].seg_id);
// only one of those should be true:
@@ -669,7 +694,7 @@ struct linear_linear
if ( first_in_range )
{
- //BOOST_ASSERT(!boost::empty(ls1_ref));
+ //BOOST_GEOMETRY_ASSERT(!boost::empty(ls1_ref));
bool const front_b = is_endpoint_on_boundary<boundary_front>(
range::front(ls1_ref), boundary_checker);
if ( front_b )
@@ -698,7 +723,7 @@ struct linear_linear
if ( first_in_range )
{
- //BOOST_ASSERT(!boost::empty(ls1_ref));
+ //BOOST_GEOMETRY_ASSERT(!boost::empty(ls1_ref));
bool const front_b = is_endpoint_on_boundary<boundary_front>(
range::front(ls1_ref), boundary_checker);
if ( front_b )
@@ -721,6 +746,7 @@ struct linear_linear
const TurnInfo * m_previous_turn_ptr;
overlay::operation_type m_previous_operation;
const TurnInfo * m_degenerated_turn_ptr;
+ bool m_collinear_spike_exit;
};
template <typename Result,
@@ -747,7 +773,7 @@ struct linear_linear
geometry, other_geometry,
boundary_checker, other_boundary_checker);
- if ( res.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION( res.interrupt ) )
return;
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/point_geometry.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/point_geometry.hpp
index 86c236d357..be08016a16 100644
--- a/3party/boost/boost/geometry/algorithms/detail/relate/point_geometry.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/point_geometry.hpp
@@ -2,15 +2,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP
@@ -18,8 +18,11 @@
//#include <boost/geometry/algorithms/within.hpp>
//#include <boost/geometry/algorithms/covered_by.hpp>
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
#include <boost/geometry/algorithms/detail/relate/topology_check.hpp>
+#include <boost/geometry/util/condition.hpp>
+
namespace boost { namespace geometry
{
@@ -41,20 +44,20 @@ struct point_geometry
if ( pig > 0 ) // within
{
- set<interior, interior, '0', Transpose>(result);
+ relate::set<interior, interior, '0', Transpose>(result);
}
else if ( pig == 0 )
{
- set<interior, boundary, '0', Transpose>(result);
+ relate::set<interior, boundary, '0', Transpose>(result);
}
else // pig < 0 - not within
{
- set<interior, exterior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
}
- set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
+ relate::set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
- if ( result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
// the point is on the boundary
@@ -67,9 +70,9 @@ struct point_geometry
typedef detail::relate::topology_check<Geometry> tc_t;
//tc_t tc(geometry, point);
//if ( tc.has_interior )
- set<exterior, interior, tc_t::interior, Transpose>(result);
+ relate::set<exterior, interior, tc_t::interior, Transpose>(result);
//if ( tc.has_boundary )
- set<exterior, boundary, tc_t::boundary, Transpose>(result);
+ relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
}
else
{
@@ -77,9 +80,9 @@ struct point_geometry
typedef detail::relate::topology_check<Geometry> tc_t;
tc_t tc(geometry);
if ( tc.has_interior )
- set<exterior, interior, tc_t::interior, Transpose>(result);
+ relate::set<exterior, interior, tc_t::interior, Transpose>(result);
if ( tc.has_boundary )
- set<exterior, boundary, tc_t::boundary, Transpose>(result);
+ relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
}
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/point_point.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/point_point.hpp
index e623868b92..e55be08225 100644
--- a/3party/boost/boost/geometry/algorithms/detail/relate/point_point.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/point_point.hpp
@@ -17,9 +17,12 @@
#include <algorithm>
#include <vector>
+#include <boost/range/empty.hpp>
+
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
#include <boost/geometry/algorithms/detail/relate/less.hpp>
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
namespace boost { namespace geometry
{
@@ -38,15 +41,15 @@ struct point_point
bool equal = detail::equals::equals_point_point(point1, point2);
if ( equal )
{
- set<interior, interior, '0'>(result);
+ relate::set<interior, interior, '0'>(result);
}
else
{
- set<interior, exterior, '0'>(result);
- set<exterior, interior, '0'>(result);
+ relate::set<interior, exterior, '0'>(result);
+ relate::set<exterior, interior, '0'>(result);
}
- set<exterior, exterior, result_dimension<Point1>::value>(result);
+ relate::set<exterior, exterior, result_dimension<Point1>::value>(result);
}
};
@@ -89,7 +92,7 @@ struct point_multipoint
if ( boost::empty(multi_point) )
{
// TODO: throw on empty input?
- set<interior, exterior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
return;
}
@@ -97,20 +100,20 @@ struct point_multipoint
if ( rel.first ) // some point of MP is equal to P
{
- set<interior, interior, '0', Transpose>(result);
+ relate::set<interior, interior, '0', Transpose>(result);
if ( rel.second ) // a point of MP was found outside P
{
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
}
}
else
{
- set<interior, exterior, '0', Transpose>(result);
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
}
- set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
+ relate::set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
}
};
@@ -144,12 +147,12 @@ struct multipoint_multipoint
}
else if ( empty1 )
{
- set<exterior, interior, '0'>(result);
+ relate::set<exterior, interior, '0'>(result);
return;
}
else if ( empty2 )
{
- set<interior, exterior, '0'>(result);
+ relate::set<interior, exterior, '0'>(result);
return;
}
}
@@ -165,7 +168,7 @@ struct multipoint_multipoint
// NlogN + MlogN
bool all_handled = search<false>(multi_point1, multi_point2, result);
- if ( all_handled || result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(all_handled || result.interrupt) )
return;
// MlogM + NlogM
@@ -212,23 +215,23 @@ struct multipoint_multipoint
// TODO: if I/I is set for one MPt, this won't be changed when the other one in analysed
// so if e.g. only I/I must be analysed we musn't check the other MPt
- set<interior, interior, '0', Transpose>(result);
+ relate::set<interior, interior, '0', Transpose>(result);
if ( found_outside ) // some point of MP2 was found outside of MP1
{
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
}
}
else
{
- set<interior, exterior, '0', Transpose>(result);
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
// if no point is intersecting the other MPt then we musn't analyse the reversed case
all_handled = true;
}
- set<exterior, exterior, result_dimension<point_type>::value, Transpose>(result);
+ relate::set<exterior, exterior, result_dimension<point_type>::value, Transpose>(result);
return all_handled;
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/relate.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/relate.hpp
deleted file mode 100644
index 946653452a..0000000000
--- a/3party/boost/boost/geometry/algorithms/detail/relate/relate.hpp
+++ /dev/null
@@ -1,339 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
-
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
-#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
-
-#include <cstddef>
-
-#include <boost/concept_check.hpp>
-#include <boost/range.hpp>
-
-#include <boost/mpl/if.hpp>
-#include <boost/mpl/or.hpp>
-#include <boost/type_traits/is_base_of.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/concepts/within_concept.hpp>
-#include <boost/geometry/strategies/default_strategy.hpp>
-#include <boost/geometry/strategies/within.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>
-
-#include <boost/geometry/algorithms/detail/relate/result.hpp>
-
-#include <boost/geometry/algorithms/detail/relate/point_point.hpp>
-#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
-#include <boost/geometry/algorithms/detail/relate/linear_linear.hpp>
-#include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
-#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace relate {
-
-// Those are used only to allow dispatch::relate to produce compile-time error
-
-template <typename Geometry,
- typename Tag = typename geometry::tag<Geometry>::type>
-struct is_supported_by_generic
-{
- static const bool value
- = boost::is_same<Tag, linestring_tag>::value
- || boost::is_same<Tag, multi_linestring_tag>::value
- || boost::is_same<Tag, ring_tag>::value
- || boost::is_same<Tag, polygon_tag>::value
- || boost::is_same<Tag, multi_polygon_tag>::value;
-};
-
-template <typename Geometry1,
- typename Geometry2,
- typename Tag1 = typename geometry::tag<Geometry1>::type,
- typename Tag2 = typename geometry::tag<Geometry2>::type>
-struct is_generic
-{
- static const bool value = is_supported_by_generic<Geometry1>::value
- && is_supported_by_generic<Geometry2>::value;
-};
-
-
-template <typename Point, typename Geometry, typename Tag>
-struct is_generic<Point, Geometry, point_tag, Tag>
-{
- static const bool value = is_supported_by_generic<Geometry>::value;
-};
-
-template <typename Geometry, typename Point, typename Tag>
-struct is_generic<Geometry, Point, Tag, point_tag>
-{
- static const bool value = is_supported_by_generic<Geometry>::value;
-};
-
-template <typename Point1, typename Point2>
-struct is_generic<Point1, Point2, point_tag, point_tag>
-{
- static const bool value = false;
-};
-
-
-}} // namespace detail::relate
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace detail_dispatch { namespace relate {
-
-
-template <typename Geometry1,
- typename Geometry2,
- typename Tag1 = typename geometry::tag<Geometry1>::type,
- typename Tag2 = typename geometry::tag<Geometry2>::type,
- int TopDim1 = geometry::topological_dimension<Geometry1>::value,
- int TopDim2 = geometry::topological_dimension<Geometry2>::value,
- bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
->
-struct relate : not_implemented<Tag1, Tag2>
-{};
-
-
-template <typename Point1, typename Point2>
-struct relate<Point1, Point2, point_tag, point_tag, 0, 0, false>
- : detail::relate::point_point<Point1, Point2>
-{};
-
-template <typename Point, typename MultiPoint>
-struct relate<Point, MultiPoint, point_tag, multi_point_tag, 0, 0, false>
- : detail::relate::point_multipoint<Point, MultiPoint>
-{};
-
-template <typename MultiPoint, typename Point>
-struct relate<MultiPoint, Point, multi_point_tag, point_tag, 0, 0, false>
- : detail::relate::multipoint_point<MultiPoint, Point>
-{};
-
-template <typename MultiPoint1, typename MultiPoint2>
-struct relate<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, 0, 0, false>
- : detail::relate::multipoint_multipoint<MultiPoint1, MultiPoint2>
-{};
-
-//template <typename Point, typename Box, int TopDim2>
-//struct relate<Point, Box, point_tag, box_tag, 0, TopDim2, false>
-// : detail::relate::point_box<Point, Box>
-//{};
-//
-//template <typename Box, typename Point, int TopDim1>
-//struct relate<Box, Point, box_tag, point_tag, TopDim1, 0, false>
-// : detail::relate::box_point<Box, Point>
-//{};
-
-
-template <typename Point, typename Geometry, typename Tag2, int TopDim2>
-struct relate<Point, Geometry, point_tag, Tag2, 0, TopDim2, true>
- : detail::relate::point_geometry<Point, Geometry>
-{};
-
-template <typename Geometry, typename Point, typename Tag1, int TopDim1>
-struct relate<Geometry, Point, Tag1, point_tag, TopDim1, 0, true>
- : detail::relate::geometry_point<Geometry, Point>
-{};
-
-
-template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
-struct relate<Linear1, Linear2, Tag1, Tag2, 1, 1, true>
- : detail::relate::linear_linear<Linear1, Linear2>
-{};
-
-
-template <typename Linear, typename Areal, typename Tag1, typename Tag2>
-struct relate<Linear, Areal, Tag1, Tag2, 1, 2, true>
- : detail::relate::linear_areal<Linear, Areal>
-{};
-
-template <typename Areal, typename Linear, typename Tag1, typename Tag2>
-struct relate<Areal, Linear, Tag1, Tag2, 2, 1, true>
- : detail::relate::areal_linear<Areal, Linear>
-{};
-
-
-template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
-struct relate<Areal1, Areal2, Tag1, Tag2, 2, 2, true>
- : detail::relate::areal_areal<Areal1, Areal2>
-{};
-
-
-}} // namespace detail_dispatch::relate
-#endif // DOXYGEN_NO_DISPATCH
-
-namespace detail { namespace relate {
-
-template <typename Geometry1, typename Geometry2>
-struct interruption_enabled
-{
- static const bool value =
- detail_dispatch::relate::relate<Geometry1, Geometry2>::interruption_enabled;
-};
-
-template <typename Geometry1,
- typename Geometry2,
- typename Result,
- bool IsSequence = boost::mpl::is_sequence<Result>::value>
-struct result_handler_type
- : not_implemented<Result>
-{};
-
-template <typename Geometry1, typename Geometry2>
-struct result_handler_type<Geometry1, Geometry2, matrix9, false>
-{
- typedef matrix_handler<matrix9> type;
-};
-
-template <typename Geometry1, typename Geometry2>
-struct result_handler_type<Geometry1, Geometry2, mask9, false>
-{
- typedef mask_handler
- <
- mask9,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename Geometry1, typename Geometry2, typename Head, typename Tail>
-struct result_handler_type<Geometry1, Geometry2, boost::tuples::cons<Head, Tail>, false>
-{
- typedef mask_handler
- <
- boost::tuples::cons<Head, Tail>,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename Geometry1, typename Geometry2,
- char II, char IB, char IE,
- char BI, char BB, char BE,
- char EI, char EB, char EE>
-struct result_handler_type<Geometry1, Geometry2, static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>, false>
-{
- typedef static_mask_handler
- <
- static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename Geometry1, typename Geometry2, typename StaticSequence>
-struct result_handler_type<Geometry1, Geometry2, StaticSequence, true>
-{
- typedef static_mask_handler
- <
- StaticSequence,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename MatrixOrMask, typename Geometry1, typename Geometry2>
-inline
-typename result_handler_type
- <
- Geometry1,
- Geometry2,
- MatrixOrMask
- >::type::result_type
-relate(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- MatrixOrMask const& matrix_or_mask = MatrixOrMask())
-{
- typedef typename result_handler_type
- <
- Geometry1,
- Geometry2,
- MatrixOrMask
- >::type handler_type;
-
- handler_type handler(matrix_or_mask);
- detail_dispatch::relate::relate<Geometry1, Geometry2>::apply(geometry1, geometry2, handler);
- return handler.result();
-}
-
-struct implemented_tag {};
-
-template <template <typename, typename> class StaticMaskTrait,
- typename Geometry1,
- typename Geometry2>
-struct relate_base
- : boost::mpl::if_
- <
- boost::mpl::or_
- <
- boost::is_base_of
- <
- nyi::not_implemented_tag,
- StaticMaskTrait<Geometry1, Geometry2>
- >,
- boost::is_base_of
- <
- nyi::not_implemented_tag,
- detail_dispatch::relate::relate<Geometry1, Geometry2>
- >
- >,
- not_implemented
- <
- typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type
- >,
- implemented_tag
- >::type
-{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
- {
- typedef typename StaticMaskTrait<Geometry1, Geometry2>::type static_mask;
- return detail::relate::relate<static_mask>(g1, g2);
- }
-};
-
-}} // namespace detail::relate
-#endif // DOXYGEN_NO_DETAIL
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/relate_impl.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/relate_impl.hpp
new file mode 100644
index 0000000000..e8e422993d
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/relate_impl.hpp
@@ -0,0 +1,80 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_RELATE_RELATE_IMPL_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_IMPL_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+namespace boost { namespace geometry {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate {
+
+struct implemented_tag {};
+
+template <template <typename, typename> class StaticMaskTrait,
+ typename Geometry1,
+ typename Geometry2>
+struct relate_impl
+ : boost::mpl::if_
+ <
+ boost::mpl::or_
+ <
+ boost::is_base_of
+ <
+ nyi::not_implemented_tag,
+ StaticMaskTrait<Geometry1, Geometry2>
+ >,
+ boost::is_base_of
+ <
+ nyi::not_implemented_tag,
+ dispatch::relate<Geometry1, Geometry2>
+ >
+ >,
+ not_implemented
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type
+ >,
+ implemented_tag
+ >::type
+{
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ {
+ typename detail::relate::result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ typename StaticMaskTrait<Geometry1, Geometry2>::type
+ >::type handler;
+
+ dispatch::relate<Geometry1, Geometry2>::apply(g1, g2, handler);
+
+ return handler.result();
+ }
+};
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_IMPL_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/result.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/result.hpp
index 1bcb5275d2..b7b9264449 100644
--- a/3party/boost/boost/geometry/algorithms/detail/relate/result.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/result.hpp
@@ -1,32 +1,36 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
-#include <boost/tuple/tuple.hpp>
+#include <cstddef>
-#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/at.hpp>
#include <boost/mpl/begin.hpp>
+#include <boost/mpl/deref.hpp>
#include <boost/mpl/end.hpp>
+#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/next.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/vector_c.hpp>
-
-#include <boost/geometry/core/topological_dimension.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/integral_constant.hpp>
-// TEMP - move this header to geometry/detail
-#include <boost/geometry/index/detail/tuples.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/exception.hpp>
+#include <boost/geometry/util/condition.hpp>
namespace boost { namespace geometry {
@@ -41,125 +45,110 @@ enum field { interior = 0, boundary = 1, exterior = 2 };
// but for safety reasons (STATIC_ASSERT) we should check if parameter D is valid and set() doesn't do that
// so some additional function could be added, e.g. set_dim()
-// matrix
+// --------------- MATRIX ----------------
-// TODO add height?
+// matrix
-template <std::size_t Width>
+template <std::size_t Height, std::size_t Width = Height>
class matrix
{
- BOOST_STATIC_ASSERT(Width == 2 || Width == 3);
-
public:
-
- static const std::size_t size = Width * Width;
+ typedef char value_type;
+ typedef std::size_t size_type;
+ typedef const char * const_iterator;
+ typedef const_iterator iterator;
+
+ static const std::size_t static_width = Width;
+ static const std::size_t static_height = Height;
+ static const std::size_t static_size = Width * Height;
inline matrix()
{
- ::memset(m_array, 'F', size);
+ ::memset(m_array, 'F', static_size);
}
template <field F1, field F2>
inline char get() const
{
- static const bool in_bounds = F1 * Width + F2 < size;
- return get_dispatch<F1, F2>(integral_constant<bool, in_bounds>());
+ BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
+ static const std::size_t index = F1 * Width + F2;
+ BOOST_STATIC_ASSERT(index < static_size);
+ return m_array[index];
}
template <field F1, field F2, char V>
inline void set()
{
- static const bool in_bounds = F1 * Width + F2 < size;
- set_dispatch<F1, F2, V>(integral_constant<bool, in_bounds>());
+ BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
+ static const std::size_t index = F1 * Width + F2;
+ BOOST_STATIC_ASSERT(index < static_size);
+ m_array[index] = V;
}
- template <field F1, field F2, char D>
- inline void update()
+ inline char operator[](std::size_t index) const
{
- static const bool in_bounds = F1 * Width + F2 < size;
- update_dispatch<F1, F2, D>(integral_constant<bool, in_bounds>());
+ BOOST_GEOMETRY_ASSERT(index < static_size);
+ return m_array[index];
}
-
- inline const char * data() const
+
+ inline const_iterator begin() const
{
return m_array;
}
-private:
- template <field F1, field F2>
- inline char get_dispatch(integral_constant<bool, true>) const
+ inline const_iterator end() const
{
- return m_array[F1 * Width + F2];
+ return m_array + static_size;
}
- template <field F1, field F2>
- inline char get_dispatch(integral_constant<bool, false>) const
+
+ inline static std::size_t size()
{
- return 'F';
+ return static_size;
}
-
- template <field F1, field F2, char V>
- inline void set_dispatch(integral_constant<bool, true>)
+
+ inline const char * data() const
{
- BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
- m_array[F1 * Width + F2] = V;
+ return m_array;
}
- template <field F1, field F2, char V>
- inline void set_dispatch(integral_constant<bool, false>)
- {}
- template <field F1, field F2, char D>
- inline void update_dispatch(integral_constant<bool, true>)
+ inline std::string str() const
{
- BOOST_STATIC_ASSERT('0' <= D && D <= '9');
- char c = m_array[F1 * Width + F2];
- if ( D > c || c > '9')
- m_array[F1 * Width + F2] = D;
+ return std::string(m_array, static_size);
}
- template <field F1, field F2, char D>
- inline void update_dispatch(integral_constant<bool, false>)
- {}
-
- char m_array[size];
-};
-
-// TODO add EnableDimensions parameter?
-
-struct matrix9 {};
-//struct matrix4 {};
-
-// matrix_width
-
-template <typename MatrixOrMask>
-struct matrix_width
- : not_implemented<MatrixOrMask>
-{};
-template <>
-struct matrix_width<matrix9>
-{
- static const std::size_t value = 3;
+private:
+ char m_array[static_size];
};
// matrix_handler
template <typename Matrix>
class matrix_handler
- : private matrix<matrix_width<Matrix>::value>
{
- typedef matrix<matrix_width<Matrix>::value> base_t;
-
public:
- typedef std::string result_type;
+ typedef Matrix result_type;
static const bool interrupt = false;
+ matrix_handler()
+ {}
+
matrix_handler(Matrix const&)
{}
- result_type result() const
+ result_type const& result() const
{
- return std::string(this->data(),
- this->data() + base_t::size);
+ return m_matrix;
+ }
+
+ result_type const& matrix() const
+ {
+ return m_matrix;
+ }
+
+ result_type & matrix()
+ {
+ return m_matrix;
}
template <field F1, field F2, char D>
@@ -167,53 +156,124 @@ public:
{
BOOST_STATIC_ASSERT('0' <= D && D <= '9');
- char const c = static_cast<base_t const&>(*this).template get<F1, F2>();
+ char const c = m_matrix.template get<F1, F2>();
return D > c || c > '9';
}
- //template <field F1, field F2>
- //inline char get() const
- //{
- // return static_cast<base_t const&>(*this).template get<F1, F2>();
- //}
-
template <field F1, field F2, char V>
inline void set()
{
- static_cast<base_t&>(*this).template set<F1, F2, V>();
+ static const bool in_bounds = F1 < Matrix::static_height
+ && F2 < Matrix::static_width;
+ typedef boost::integral_constant<bool, in_bounds> in_bounds_t;
+ set_dispatch<F1, F2, V>(in_bounds_t());
}
template <field F1, field F2, char D>
inline void update()
{
- static_cast<base_t&>(*this).template update<F1, F2, D>();
+ static const bool in_bounds = F1 < Matrix::static_height
+ && F2 < Matrix::static_width;
+ typedef boost::integral_constant<bool, in_bounds> in_bounds_t;
+ update_dispatch<F1, F2, D>(in_bounds_t());
+ }
+
+private:
+ template <field F1, field F2, char V>
+ inline void set_dispatch(integral_constant<bool, true>)
+ {
+ static const std::size_t index = F1 * Matrix::static_width + F2;
+ BOOST_STATIC_ASSERT(index < Matrix::static_size);
+ BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
+ m_matrix.template set<F1, F2, V>();
+ }
+ template <field F1, field F2, char V>
+ inline void set_dispatch(integral_constant<bool, false>)
+ {}
+
+ template <field F1, field F2, char D>
+ inline void update_dispatch(integral_constant<bool, true>)
+ {
+ static const std::size_t index = F1 * Matrix::static_width + F2;
+ BOOST_STATIC_ASSERT(index < Matrix::static_size);
+ BOOST_STATIC_ASSERT('0' <= D && D <= '9');
+ char const c = m_matrix.template get<F1, F2>();
+ if ( D > c || c > '9')
+ m_matrix.template set<F1, F2, D>();
}
+ template <field F1, field F2, char D>
+ inline void update_dispatch(integral_constant<bool, false>)
+ {}
+
+ Matrix m_matrix;
};
-// RUN-TIME MASKS
+// --------------- RUN-TIME MASK ----------------
-// mask9
+// run-time mask
-class mask9
+template <std::size_t Height, std::size_t Width = Height>
+class mask
{
public:
- static const std::size_t width = 3; // TEMP
+ static const std::size_t static_width = Width;
+ static const std::size_t static_height = Height;
+ static const std::size_t static_size = Width * Height;
- inline mask9(std::string const& de9im_mask)
+ inline mask(const char * s)
{
- // TODO: throw an exception here?
- BOOST_ASSERT(de9im_mask.size() == 9);
- ::memcpy(m_mask, de9im_mask.c_str(), 9);
+ char * it = m_array;
+ char * const last = m_array + static_size;
+ for ( ; it != last && *s != '\0' ; ++it, ++s )
+ {
+ char c = *s;
+ check_char(c);
+ *it = c;
+ }
+ if ( it != last )
+ {
+ ::memset(it, '*', last - it);
+ }
+ }
+
+ inline mask(const char * s, std::size_t count)
+ {
+ if ( count > static_size )
+ {
+ count = static_size;
+ }
+ if ( count > 0 )
+ {
+ std::for_each(s, s + count, check_char);
+ ::memcpy(m_array, s, count);
+ }
+ if ( count < static_size )
+ {
+ ::memset(m_array + count, '*', static_size - count);
+ }
}
template <field F1, field F2>
inline char get() const
{
- return m_mask[F1 * 3 + F2];
+ BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
+ static const std::size_t index = F1 * Width + F2;
+ BOOST_STATIC_ASSERT(index < static_size);
+ return m_array[index];
}
private:
- char m_mask[9];
+ static inline void check_char(char c)
+ {
+ bool const is_valid = c == '*' || c == 'T' || c == 'F'
+ || ( c >= '0' && c <= '9' );
+ if ( !is_valid )
+ {
+ throw geometry::invalid_input_exception();
+ }
+ }
+
+ char m_array[static_size];
};
// interrupt()
@@ -235,17 +295,17 @@ struct interrupt_dispatch<Mask, true>
static inline bool apply(Mask const& mask)
{
char m = mask.template get<F1, F2>();
- return check<V>(m);
+ return check_element<V>(m);
}
template <char V>
- static inline bool check(char m)
+ static inline bool check_element(char m)
{
- if ( V >= '0' && V <= '9' )
+ if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') )
{
return m == 'F' || ( m < V && m >= '0' && m <= '9' );
}
- else if ( V == 'T' )
+ else if ( BOOST_GEOMETRY_CONDITION(V == 'T') )
{
return m == 'F';
}
@@ -276,18 +336,18 @@ struct interrupt_dispatch_tuple<Masks, N, N>
}
};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-struct interrupt_dispatch<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, true>
-{
- typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
+//template <typename T0, typename T1, typename T2, typename T3, typename T4,
+// typename T5, typename T6, typename T7, typename T8, typename T9>
+//struct interrupt_dispatch<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, true>
+//{
+// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
- template <field F1, field F2, char V>
- static inline bool apply(mask_type const& mask)
- {
- return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
- }
-};
+// template <field F1, field F2, char V>
+// static inline bool apply(mask_type const& mask)
+// {
+// return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
+// }
+//};
template <typename Head, typename Tail>
struct interrupt_dispatch<boost::tuples::cons<Head, Tail>, true>
@@ -362,18 +422,18 @@ struct may_update_dispatch_tuple<Masks, N, N>
}
};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-struct may_update_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
-{
- typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
+//template <typename T0, typename T1, typename T2, typename T3, typename T4,
+// typename T5, typename T6, typename T7, typename T8, typename T9>
+//struct may_update_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
+//{
+// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
- template <field F1, field F2, char D, typename Matrix>
- static inline bool apply(mask_type const& mask, Matrix const& matrix)
- {
- return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
- }
-};
+// template <field F1, field F2, char D, typename Matrix>
+// static inline bool apply(mask_type const& mask, Matrix const& matrix)
+// {
+// return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
+// }
+//};
template <typename Head, typename Tail>
struct may_update_dispatch< boost::tuples::cons<Head, Tail> >
@@ -394,7 +454,7 @@ inline bool may_update(Mask const& mask, Matrix const& matrix)
::template apply<F1, F2, D>(mask, matrix);
}
-// check()
+// check_matrix()
template <typename Mask>
struct check_dispatch
@@ -459,18 +519,18 @@ struct check_dispatch_tuple<Masks, N, N>
}
};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-struct check_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
-{
- typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
+//template <typename T0, typename T1, typename T2, typename T3, typename T4,
+// typename T5, typename T6, typename T7, typename T8, typename T9>
+//struct check_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
+//{
+// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
- template <typename Matrix>
- static inline bool apply(mask_type const& mask, Matrix const& matrix)
- {
- return check_dispatch_tuple<mask_type>::apply(mask, matrix);
- }
-};
+// template <typename Matrix>
+// static inline bool apply(mask_type const& mask, Matrix const& matrix)
+// {
+// return check_dispatch_tuple<mask_type>::apply(mask, matrix);
+// }
+//};
template <typename Head, typename Tail>
struct check_dispatch< boost::tuples::cons<Head, Tail> >
@@ -485,17 +545,17 @@ struct check_dispatch< boost::tuples::cons<Head, Tail> >
};
template <typename Mask, typename Matrix>
-inline bool check(Mask const& mask, Matrix const& matrix)
+inline bool check_matrix(Mask const& mask, Matrix const& matrix)
{
return check_dispatch<Mask>::apply(mask, matrix);
}
// matrix_width
-template <>
-struct matrix_width<mask9>
+template <typename MatrixOrMask>
+struct matrix_width
{
- static const std::size_t value = 3;
+ static const std::size_t value = MatrixOrMask::static_width;
};
template <typename Tuple,
@@ -525,20 +585,30 @@ struct matrix_width< boost::tuples::cons<Head, Tail> >
value = matrix_width_tuple< boost::tuples::cons<Head, Tail> >::value;
};
-// matrix_handler
+// mask_handler
template <typename Mask, bool Interrupt>
class mask_handler
- : private matrix<matrix_width<Mask>::value>
+ : private matrix_handler
+ <
+ relate::matrix<matrix_width<Mask>::value>
+ >
{
- typedef matrix<matrix_width<Mask>::value> base_t;
+ typedef matrix_handler
+ <
+ relate::matrix<matrix_width<Mask>::value>
+ > base_t;
public:
typedef bool result_type;
bool interrupt;
- inline mask_handler(Mask const& m)
+ inline mask_handler()
+ : interrupt(false)
+ {}
+
+ inline explicit mask_handler(Mask const& m)
: interrupt(false)
, m_mask(m)
{}
@@ -546,23 +616,17 @@ public:
result_type result() const
{
return !interrupt
- && check(m_mask, static_cast<base_t const&>(*this));
+ && check_matrix(m_mask, base_t::matrix());
}
template <field F1, field F2, char D>
inline bool may_update() const
{
return detail::relate::may_update<F1, F2, D>(
- m_mask, static_cast<base_t const&>(*this)
+ m_mask, base_t::matrix()
);
}
- //template <field F1, field F2>
- //inline char get() const
- //{
- // return static_cast<base_t const&>(*this).template get<F1, F2>();
- //}
-
template <field F1, field F2, char V>
inline void set()
{
@@ -593,29 +657,65 @@ private:
Mask const& m_mask;
};
-// STATIC MASKS
+// --------------- COMPILE-TIME MASK ----------------
+
+// static_check_characters
+template
+<
+ typename Seq,
+ typename First = typename boost::mpl::begin<Seq>::type,
+ typename Last = typename boost::mpl::end<Seq>::type
+>
+struct static_check_characters
+ : static_check_characters
+ <
+ Seq,
+ typename boost::mpl::next<First>::type
+ >
+{
+ typedef typename boost::mpl::deref<First>::type type;
+ static const char value = type::value;
+ static const bool is_valid = (value >= '0' && value <= '9')
+ || value == 'T' || value == 'F' || value == '*';
+ BOOST_MPL_ASSERT_MSG((is_valid),
+ INVALID_STATIC_MASK_CHARACTER,
+ (type));
+};
+
+template <typename Seq, typename Last>
+struct static_check_characters<Seq, Last, Last>
+{};
// static_mask
-template <char II, char IB, char IE,
- char BI, char BB, char BE,
- char EI, char EB, char EE>
-class static_mask
+template
+<
+ typename Seq,
+ std::size_t Height,
+ std::size_t Width = Height
+>
+struct static_mask
{
- typedef boost::mpl::vector_c
- <
- char, II, IB, IE, BI, BB, BE, EI, EB, EE
- > vector_type;
+ static const std::size_t static_width = Width;
+ static const std::size_t static_height = Height;
+ static const std::size_t static_size = Width * Height;
-public:
- template <field F1, field F2>
- struct get
+ BOOST_STATIC_ASSERT(
+ std::size_t(boost::mpl::size<Seq>::type::value) == static_size);
+
+ template <detail::relate::field F1, detail::relate::field F2>
+ struct static_get
{
- BOOST_STATIC_ASSERT(F1 * 3 + F2 < boost::mpl::size<vector_type>::value);
+ BOOST_STATIC_ASSERT(std::size_t(F1) < static_height);
+ BOOST_STATIC_ASSERT(std::size_t(F2) < static_width);
static const char value
- = boost::mpl::at_c<vector_type, F1 * 3 + F2>::type::value;
+ = boost::mpl::at_c<Seq, F1 * static_width + F2>::type::value;
};
+
+private:
+ // check static_mask characters
+ enum { mask_check = sizeof(static_check_characters<Seq>) };
};
// static_should_handle_element
@@ -623,7 +723,7 @@ public:
template <typename StaticMask, field F1, field F2, bool IsSequence>
struct static_should_handle_element_dispatch
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const bool value = mask_el == 'F'
|| mask_el == 'T'
|| ( mask_el >= '0' && mask_el <= '9' );
@@ -690,7 +790,7 @@ struct static_interrupt_dispatch
template <typename StaticMask, char V, field F1, field F2, bool IsSequence>
struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, IsSequence>
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const bool value
= ( V >= '0' && V <= '9' ) ?
@@ -755,7 +855,7 @@ struct static_interrupt
template <typename StaticMask, char D, field F1, field F2, bool IsSequence>
struct static_may_update_dispatch
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const int version
= mask_el == 'F' ? 0
: mask_el == 'T' ? 1
@@ -859,7 +959,7 @@ struct static_may_update
}
};
-// static_check
+// static_check_matrix
template <typename StaticMask, bool IsSequence>
struct static_check_dispatch
@@ -881,7 +981,7 @@ struct static_check_dispatch
template <field F1, field F2>
struct per_one
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const int version
= mask_el == 'F' ? 0
: mask_el == 'T' ? 1
@@ -964,7 +1064,7 @@ struct static_check_dispatch<StaticMask, true>
};
template <typename StaticMask>
-struct static_check
+struct static_check_matrix
{
template <typename Matrix>
static inline bool apply(Matrix const& matrix)
@@ -981,31 +1081,34 @@ struct static_check
template <typename StaticMask, bool Interrupt>
class static_mask_handler
- : private matrix<3>
+ : private matrix_handler< matrix<3> >
{
- typedef matrix<3> base_t;
+ typedef matrix_handler< relate::matrix<3> > base_type;
public:
typedef bool result_type;
bool interrupt;
- inline static_mask_handler(StaticMask const& /*dummy*/)
+ inline static_mask_handler()
+ : interrupt(false)
+ {}
+
+ inline explicit static_mask_handler(StaticMask const& /*dummy*/)
: interrupt(false)
{}
result_type result() const
{
return (!Interrupt || !interrupt)
- && static_check<StaticMask>::
- apply(static_cast<base_t const&>(*this));
+ && static_check_matrix<StaticMask>::apply(base_type::matrix());
}
template <field F1, field F2, char D>
inline bool may_update() const
{
return static_may_update<StaticMask, D, F1, F2>::
- apply(static_cast<base_t const&>(*this));
+ apply(base_type::matrix());
}
template <field F1, field F2>
@@ -1014,12 +1117,6 @@ public:
return static_should_handle_element<StaticMask, F1, F2>::value;
}
- //template <field F1, field F2>
- //inline char get() const
- //{
- // return base_t::template get<F1, F2>();
- //}
-
template <field F1, field F2, char V>
inline void set()
{
@@ -1055,7 +1152,7 @@ private:
template <field F1, field F2, char V>
inline void set_dispatch(integral_constant<int, 1>)
{
- base_t::template set<F1, F2, V>();
+ base_type::template set<F1, F2, V>();
}
// else
template <field F1, field F2, char V>
@@ -1072,7 +1169,7 @@ private:
template <field F1, field F2, char V>
inline void update_dispatch(integral_constant<int, 1>)
{
- base_t::template update<F1, F2, V>();
+ base_type::template update<F1, F2, V>();
}
// else
template <field F1, field F2, char V>
@@ -1080,165 +1177,9 @@ private:
{}
};
-// OPERATORS
-
-template <typename Mask1, typename Mask2> inline
-boost::tuples::cons<
- Mask1,
- boost::tuples::cons<Mask2, boost::tuples::null_type>
->
-operator||(Mask1 const& m1, Mask2 const& m2)
-{
- namespace bt = boost::tuples;
-
- return
- bt::cons< Mask1, bt::cons<Mask2, bt::null_type> >
- ( m1, bt::cons<Mask2, bt::null_type>(m2, bt::null_type()) );
-}
-
-template <typename Head, typename Tail, typename Mask> inline
-typename index::detail::tuples::push_back<
- boost::tuples::cons<Head, Tail>, Mask
->::type
-operator||(boost::tuples::cons<Head, Tail> const& t, Mask const& m)
-{
- namespace bt = boost::tuples;
-
- return
- index::detail::tuples::push_back<
- bt::cons<Head, Tail>, Mask
- >::apply(t, m);
-}
-
-// PREDEFINED MASKS
-
-// TODO:
-// 1. specialize for simplified masks if available
-// e.g. for TOUCHES use 1 mask for A/A
-// 2. Think about dimensions > 2 e.g. should TOUCHES be true
-// if the interior of the Areal overlaps the boundary of the Volumetric
-// like it's true for Linear/Areal
-
-// EQUALS
-template <typename Geometry1, typename Geometry2>
-struct static_mask_equals_type
-{
- typedef static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
- //typedef static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
-};
-
-// DISJOINT
-typedef static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> static_mask_disjoint;
-
-// TOUCHES - NOT P/P
-template <typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = topological_dimension<Geometry1>::value,
- std::size_t Dim2 = topological_dimension<Geometry2>::value>
-struct static_mask_touches_impl
-{
- typedef boost::mpl::vector<
- static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
- static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
- static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
- > type;
-};
-// According to OGC, doesn't apply to P/P
-// Using the above mask the result would be always false
-template <typename Geometry1, typename Geometry2>
-struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
- : not_implemented<typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type>
-{};
-
-template <typename Geometry1, typename Geometry2>
-struct static_mask_touches_type
- : static_mask_touches_impl<Geometry1, Geometry2>
-{};
-
-// WITHIN
-typedef static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> static_mask_within;
-
-// COVERED_BY (non OGC)
-typedef boost::mpl::vector<
- static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
- static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
- static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
- static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
- > static_mask_covered_by;
-
-// CROSSES
-// dim(G1) < dim(G2) - P/L P/A L/A
-template <typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = topological_dimension<Geometry1>::value,
- std::size_t Dim2 = topological_dimension<Geometry2>::value,
- bool D1LessD2 = (Dim1 < Dim2)
->
-struct static_mask_crosses_impl
-{
- typedef static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
-};
-// TODO: I'm not sure if this one below should be available!
-// dim(G1) > dim(G2) - L/P A/P A/L
-template <typename Geometry1, typename Geometry2,
- std::size_t Dim1, std::size_t Dim2
->
-struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
-{
- typedef static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
-};
-// dim(G1) == dim(G2) - P/P A/A
-template <typename Geometry1, typename Geometry2,
- std::size_t Dim
->
-struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
- : not_implemented<typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type>
-{};
-// dim(G1) == 1 && dim(G2) == 1 - L/L
-template <typename Geometry1, typename Geometry2>
-struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
-{
- typedef static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
-};
-
-template <typename Geometry1, typename Geometry2>
-struct static_mask_crosses_type
- : static_mask_crosses_impl<Geometry1, Geometry2>
-{};
+// --------------- UTIL FUNCTIONS ----------------
-// OVERLAPS
-
-// dim(G1) != dim(G2) - NOT P/P, L/L, A/A
-template <typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = topological_dimension<Geometry1>::value,
- std::size_t Dim2 = topological_dimension<Geometry2>::value
->
-struct static_mask_overlaps_impl
- : not_implemented<typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type>
-{};
-// dim(G1) == D && dim(G2) == D - P/P A/A
-template <typename Geometry1, typename Geometry2, std::size_t Dim>
-struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
-{
- typedef static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
-};
-// dim(G1) == 1 && dim(G2) == 1 - L/L
-template <typename Geometry1, typename Geometry2>
-struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
-{
- typedef static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
-};
-
-template <typename Geometry1, typename Geometry2>
-struct static_mask_overlaps_type
- : static_mask_overlaps_impl<Geometry1, Geometry2>
-{};
-
-// RESULTS/HANDLERS UTILS
+// set
template <field F1, field F2, char V, typename Result>
inline void set(Result & res)
@@ -1272,33 +1213,7 @@ inline void set(Result & res)
set_dispatch<F1, F2, V, Transpose>::apply(res);
}
-template <char V, typename Result>
-inline void set(Result & res)
-{
- res.template set<interior, interior, V>();
- res.template set<interior, boundary, V>();
- res.template set<interior, exterior, V>();
- res.template set<boundary, interior, V>();
- res.template set<boundary, boundary, V>();
- res.template set<boundary, exterior, V>();
- res.template set<exterior, interior, V>();
- res.template set<exterior, boundary, V>();
- res.template set<exterior, exterior, V>();
-}
-
-template <char II, char IB, char IE, char BI, char BB, char BE, char EI, char EB, char EE, typename Result>
-inline void set(Result & res)
-{
- res.template set<interior, interior, II>();
- res.template set<interior, boundary, IB>();
- res.template set<interior, exterior, IE>();
- res.template set<boundary, interior, BI>();
- res.template set<boundary, boundary, BB>();
- res.template set<boundary, exterior, BE>();
- res.template set<exterior, interior, EI>();
- res.template set<exterior, boundary, EB>();
- res.template set<exterior, exterior, EE>();
-}
+// update
template <field F1, field F2, char D, typename Result>
inline void update(Result & res)
@@ -1332,6 +1247,8 @@ inline void update(Result & res)
update_result_dispatch<F1, F2, D, Transpose>::apply(res);
}
+// may_update
+
template <field F1, field F2, char D, typename Result>
inline bool may_update(Result const& res)
{
@@ -1364,13 +1281,7 @@ inline bool may_update(Result const& res)
return may_update_result_dispatch<F1, F2, D, Transpose>::apply(res);
}
-template <typename Result, char II, char IB, char IE, char BI, char BB, char BE, char EI, char EB, char EE>
-inline Result return_result()
-{
- Result res;
- set<II, IB, IE, BI, BB, BE, EI, EB, EE>(res);
- return res;
-}
+// result_dimension
template <typename Geometry>
struct result_dimension
diff --git a/3party/boost/boost/geometry/algorithms/detail/relate/turns.hpp b/3party/boost/boost/geometry/algorithms/detail/relate/turns.hpp
index b8c292bee7..636c9756d8 100644
--- a/3party/boost/boost/geometry/algorithms/detail/relate/turns.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/relate/turns.hpp
@@ -1,16 +1,17 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_TURNS_HPP
@@ -19,8 +20,12 @@
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
+#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
+#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
+
#include <boost/type_traits/is_base_of.hpp>
+
namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
@@ -35,10 +40,16 @@ struct assign_policy
// GET_TURNS
-template <typename Geometry1,
- typename Geometry2,
- typename GetTurnPolicy
- = detail::get_turns::get_turn_info_type<Geometry1, Geometry2, assign_policy<> > >
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename GetTurnPolicy = detail::get_turns::get_turn_info_type
+ <
+ Geometry1, Geometry2, assign_policy<>
+ >,
+ typename RobustPolicy = detail::no_rescale_policy
+>
struct get_turns
{
typedef typename geometry::point_type<Geometry1>::type point1_type;
@@ -46,11 +57,14 @@ struct get_turns
typedef overlay::turn_info
<
point1_type,
- typename segment_ratio_type<point1_type, detail::no_rescale_policy>::type,
+ typename segment_ratio_type<point1_type, RobustPolicy>::type,
typename detail::get_turns::turn_operation_type
<
Geometry1, Geometry2,
- typename segment_ratio_type<point1_type, detail::no_rescale_policy>::type
+ typename segment_ratio_type
+ <
+ point1_type, RobustPolicy
+ >::type
>::type
> turn_info;
@@ -73,6 +87,12 @@ struct get_turns
static const bool reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value;
static const bool reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value;
+ RobustPolicy robust_policy = geometry::get_rescale_policy
+ <
+ RobustPolicy
+ >(geometry1, geometry2);
+
+
dispatch::get_turns
<
typename geometry::tag<Geometry1>::type,
@@ -83,7 +103,7 @@ struct get_turns
reverse2,
GetTurnPolicy
>::apply(0, geometry1, 1, geometry2,
- detail::no_rescale_policy(), turns, interrupt_policy);
+ robust_policy, turns, interrupt_policy);
}
};
@@ -92,8 +112,8 @@ struct get_turns
template <int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0>
struct op_to_int
{
- template <typename Op>
- inline int operator()(Op const& op) const
+ template <typename SegmentRatio>
+ inline int operator()(detail::overlay::turn_operation<SegmentRatio> const& op) const
{
switch(op.operation)
{
@@ -108,106 +128,136 @@ struct op_to_int
}
};
-template <typename OpToInt>
+template <std::size_t OpId, typename OpToInt>
struct less_op_xxx_linear
{
- template <typename Op>
- inline bool operator()(Op const& left, Op const& right)
+ template <typename Turn>
+ inline bool operator()(Turn const& left, Turn const& right) const
{
static OpToInt op_to_int;
- return op_to_int(left) < op_to_int(right);
+ return op_to_int(left.operations[OpId]) < op_to_int(right.operations[OpId]);
}
};
+template <std::size_t OpId>
struct less_op_linear_linear
- : less_op_xxx_linear< op_to_int<0,2,3,1,4,0> >
+ : less_op_xxx_linear< OpId, op_to_int<0,2,3,1,4,0> >
{};
-struct less_op_linear_areal
+template <std::size_t OpId>
+struct less_op_linear_areal_single
{
- template <typename Op>
- inline bool operator()(Op const& left, Op const& right)
+ template <typename Turn>
+ inline bool operator()(Turn const& left, Turn const& right) const
{
+ static const std::size_t other_op_id = (OpId + 1) % 2;
static turns::op_to_int<0,2,3,1,4,0> op_to_int_xuic;
static turns::op_to_int<0,3,2,1,4,0> op_to_int_xiuc;
- if ( left.other_id.multi_index == right.other_id.multi_index )
+ segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id;
+ segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id;
+
+ typedef typename Turn::turn_operation_type operation_type;
+ operation_type const& left_operation = left.operations[OpId];
+ operation_type const& right_operation = right.operations[OpId];
+
+ if ( left_other_seg_id.ring_index == right_other_seg_id.ring_index )
{
- if ( left.other_id.ring_index == right.other_id.ring_index )
- return op_to_int_xuic(left) < op_to_int_xuic(right);
- else
- return op_to_int_xiuc(left) < op_to_int_xiuc(right);
+ return op_to_int_xuic(left_operation)
+ < op_to_int_xuic(right_operation);
}
else
{
- //return op_to_int_xuic(left) < op_to_int_xuic(right);
- return left.other_id.multi_index < right.other_id.multi_index;
+ return op_to_int_xiuc(left_operation)
+ < op_to_int_xiuc(right_operation);
}
}
};
+template <std::size_t OpId>
struct less_op_areal_linear
- : less_op_xxx_linear< op_to_int<0,1,0,0,2,0> >
+ : less_op_xxx_linear< OpId, op_to_int<0,1,0,0,2,0> >
{};
+template <std::size_t OpId>
struct less_op_areal_areal
{
- template <typename Op>
- inline bool operator()(Op const& left, Op const& right)
+ template <typename Turn>
+ inline bool operator()(Turn const& left, Turn const& right) const
{
+ static const std::size_t other_op_id = (OpId + 1) % 2;
static op_to_int<0, 1, 2, 3, 4, 0> op_to_int_uixc;
static op_to_int<0, 2, 1, 3, 4, 0> op_to_int_iuxc;
- if ( left.other_id.multi_index == right.other_id.multi_index )
+ segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id;
+ segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id;
+
+ typedef typename Turn::turn_operation_type operation_type;
+ operation_type const& left_operation = left.operations[OpId];
+ operation_type const& right_operation = right.operations[OpId];
+
+ if ( left_other_seg_id.multi_index == right_other_seg_id.multi_index )
{
- if ( left.other_id.ring_index == right.other_id.ring_index )
+ if ( left_other_seg_id.ring_index == right_other_seg_id.ring_index )
{
- return op_to_int_uixc(left) < op_to_int_uixc(right);
+ return op_to_int_uixc(left_operation) < op_to_int_uixc(right_operation);
}
else
{
- if ( left.other_id.ring_index == -1 )
+ if ( left_other_seg_id.ring_index == -1 )
{
- if ( left.operation == overlay::operation_union )
+ if ( left_operation.operation == overlay::operation_union )
return false;
- else if ( left.operation == overlay::operation_intersection )
+ else if ( left_operation.operation == overlay::operation_intersection )
return true;
}
- else if ( right.other_id.ring_index == -1 )
+ else if ( right_other_seg_id.ring_index == -1 )
{
- if ( right.operation == overlay::operation_union )
+ if ( right_operation.operation == overlay::operation_union )
return true;
- else if ( right.operation == overlay::operation_intersection )
+ else if ( right_operation.operation == overlay::operation_intersection )
return false;
}
- return op_to_int_iuxc(left) < op_to_int_iuxc(right);
+ return op_to_int_iuxc(left_operation) < op_to_int_iuxc(right_operation);
}
}
else
{
- return op_to_int_uixc(left) < op_to_int_uixc(right);
+ return op_to_int_uixc(left_operation) < op_to_int_uixc(right_operation);
}
}
};
+template <std::size_t OpId>
+struct less_other_multi_index
+{
+ static const std::size_t other_op_id = (OpId + 1) % 2;
+
+ template <typename Turn>
+ inline bool operator()(Turn const& left, Turn const& right) const
+ {
+ return left.operations[other_op_id].seg_id.multi_index
+ < right.operations[other_op_id].seg_id.multi_index;
+ }
+};
+
// sort turns by G1 - source_index == 0 by:
// seg_id -> distance -> operation
template <std::size_t OpId = 0,
- typename LessOp = less_op_xxx_linear< op_to_int<> > >
+ typename LessOp = less_op_xxx_linear< OpId, op_to_int<> > >
struct less
{
BOOST_STATIC_ASSERT(OpId < 2);
- template <typename Op> static inline
- bool use_fraction(Op const& left, Op const& right)
+ template <typename Turn>
+ static inline bool use_fraction(Turn const& left, Turn const& right)
{
static LessOp less_op;
- if ( left.fraction == right.fraction )
- return less_op(left, right);
- else
- return left.fraction < right.fraction;
+ return left.operations[OpId].fraction < right.operations[OpId].fraction
+ || ( left.operations[OpId].fraction == right.operations[OpId].fraction
+ && less_op(left, right) );
}
template <typename Turn>
@@ -216,7 +266,7 @@ struct less
segment_identifier const& sl = left.operations[OpId].seg_id;
segment_identifier const& sr = right.operations[OpId].seg_id;
- return sl < sr || ( sl == sr && use_fraction(left.operations[OpId], right.operations[OpId]) );
+ return sl < sr || ( sl == sr && use_fraction(left, right) );
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/relation/implementation.hpp b/3party/boost/boost/geometry/algorithms/detail/relation/implementation.hpp
new file mode 100644
index 0000000000..b9a238d6c8
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/relation/implementation.hpp
@@ -0,0 +1,18 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_RELATION_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATION_IMPLEMENTATION_HPP
+
+
+#include <boost/geometry/algorithms/detail/relate/implementation.hpp>
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATION_IMPLEMENTATION_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/relation/interface.hpp b/3party/boost/boost/geometry/algorithms/detail/relation/interface.hpp
new file mode 100644
index 0000000000..73737cf2c2
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/relation/interface.hpp
@@ -0,0 +1,186 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_RELATION_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATION_INTERFACE_HPP
+
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate
+{
+
+template <typename Geometry1, typename Geometry2>
+struct result_handler_type<Geometry1, Geometry2, geometry::de9im::matrix, false>
+{
+ typedef matrix_handler<geometry::de9im::matrix> type;
+};
+
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry1, typename Geometry2>
+struct relation
+{
+ template <typename Matrix>
+ static inline Matrix apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2)
+ {
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ typename detail::relate::result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ Matrix
+ >::type handler;
+
+ dispatch::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, handler);
+
+ return handler.result();
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct relation<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename Matrix>
+ struct visitor : boost::static_visitor<Matrix>
+ {
+ Geometry2 const& m_geometry2;
+
+ visitor(Geometry2 const& geometry2)
+ : m_geometry2(geometry2) {}
+
+ template <typename Geometry1>
+ Matrix operator()(Geometry1 const& geometry1) const
+ {
+ return relation<Geometry1, Geometry2>
+ ::template apply<Matrix>(geometry1, m_geometry2);
+ }
+ };
+
+ template <typename Matrix>
+ static inline Matrix
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2)
+ {
+ return boost::apply_visitor(visitor<Matrix>(geometry2), geometry1);
+ }
+};
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct relation<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Matrix>
+ struct visitor : boost::static_visitor<Matrix>
+ {
+ Geometry1 const& m_geometry1;
+
+ visitor(Geometry1 const& geometry1)
+ : m_geometry1(geometry1) {}
+
+ template <typename Geometry2>
+ Matrix operator()(Geometry2 const& geometry2) const
+ {
+ return relation<Geometry1, Geometry2>
+ ::template apply<Matrix>(m_geometry1, geometry2);
+ }
+ };
+
+ template <typename Matrix>
+ static inline Matrix
+ apply(Geometry1 const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
+ {
+ return boost::apply_visitor(visitor<Matrix>(geometry1), geometry2);
+ }
+};
+
+template
+<
+ BOOST_VARIANT_ENUM_PARAMS(typename T1),
+ BOOST_VARIANT_ENUM_PARAMS(typename T2)
+>
+struct relation
+ <
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
+ >
+{
+ template <typename Matrix>
+ struct visitor : boost::static_visitor<Matrix>
+ {
+ template <typename Geometry1, typename Geometry2>
+ Matrix operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ return relation<Geometry1, Geometry2>
+ ::template apply<Matrix>(geometry1, geometry2);
+ }
+ };
+
+ template <typename Matrix>
+ static inline Matrix
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
+ {
+ return boost::apply_visitor(visitor<Matrix>(), geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/*!
+\brief Calculates the relation between a pair of geometries as defined in DE-9IM.
+\ingroup relation
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return The DE-9IM matrix expressing the relation between geometries.
+
+\qbk{[include reference/algorithms/relation.qbk]}
+ */
+template <typename Geometry1, typename Geometry2>
+inline de9im::matrix relation(Geometry1 const& geometry1,
+ Geometry2 const& geometry2)
+{
+ return resolve_variant::relation
+ <
+ Geometry1,
+ Geometry2
+ >::template apply<de9im::matrix>(geometry1, geometry2);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/ring_identifier.hpp b/3party/boost/boost/geometry/algorithms/detail/ring_identifier.hpp
index 9209ee0304..bc3fe1fef3 100644
--- a/3party/boost/boost/geometry/algorithms/detail/ring_identifier.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/ring_identifier.hpp
@@ -10,6 +10,14 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP
+#if defined(BOOST_GEOMETRY_DEBUG_IDENTIFIER)
+#include <iostream>
+#endif
+
+
+#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
+
+
namespace boost { namespace geometry
{
@@ -24,7 +32,9 @@ struct ring_identifier
, ring_index(-1)
{}
- inline ring_identifier(int src, int mul, int rin)
+ inline ring_identifier(signed_index_type src,
+ signed_index_type mul,
+ signed_index_type rin)
: source_index(src)
, multi_index(mul)
, ring_index(rin)
@@ -58,9 +68,9 @@ struct ring_identifier
#endif
- int source_index;
- int multi_index;
- int ring_index;
+ signed_index_type source_index;
+ signed_index_type multi_index;
+ signed_index_type ring_index;
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/sections/range_by_section.hpp b/3party/boost/boost/geometry/algorithms/detail/sections/range_by_section.hpp
index 4ef11175f7..02cec6cb48 100644
--- a/3party/boost/boost/geometry/algorithms/detail/sections/range_by_section.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/sections/range_by_section.hpp
@@ -7,8 +7,8 @@
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013.
-// Modifications copyright (c) 2013, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014.
+// Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -19,17 +19,18 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.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/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -57,7 +58,8 @@ struct full_section_polygon
{
return section.ring_id.ring_index < 0
? geometry::exterior_ring(polygon)
- : geometry::interior_rings(polygon)[section.ring_id.ring_index];
+ : range::at(geometry::interior_rings(polygon),
+ static_cast<std::size_t>(section.ring_id.ring_index));
}
};
@@ -73,13 +75,15 @@ struct full_section_multi
static inline typename ring_return_type<MultiGeometry const>::type apply(
MultiGeometry const& multi, Section const& section)
{
- BOOST_ASSERT
+ typedef typename boost::range_size<MultiGeometry>::type size_type;
+
+ BOOST_GEOMETRY_ASSERT
(
section.ring_id.multi_index >= 0
- && section.ring_id.multi_index < int(boost::size(multi))
+ && size_type(section.ring_id.multi_index) < boost::size(multi)
);
- return Policy::apply(multi[section.ring_id.multi_index], section);
+ return Policy::apply(range::at(multi, size_type(section.ring_id.multi_index)), section);
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/sections/section_box_policies.hpp b/3party/boost/boost/geometry/algorithms/detail/sections/section_box_policies.hpp
new file mode 100644
index 0000000000..cf06700306
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/sections/section_box_policies.hpp
@@ -0,0 +1,49 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 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_SECTIONS_SECTION_BOX_POLICIES_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTION_BOX_POLICIES_HPP
+
+
+#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace section
+{
+
+struct get_section_box
+{
+ template <typename Box, typename Section>
+ static inline void apply(Box& total, Section const& section)
+ {
+ geometry::expand(total, section.bounding_box);
+ }
+};
+
+struct overlaps_section_box
+{
+ template <typename Box, typename Section>
+ static inline bool apply(Box const& box, Section const& section)
+ {
+ return ! detail::disjoint::disjoint_box_box(box, section.bounding_box);
+ }
+};
+
+
+}} // namespace detail::section
+#endif
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTION_BOX_POLICIES_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/sections/section_functions.hpp b/3party/boost/boost/geometry/algorithms/detail/sections/section_functions.hpp
new file mode 100644
index 0000000000..ba1cf931b2
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/sections/section_functions.hpp
@@ -0,0 +1,66 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 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_SECTIONS_FUNCTIONS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_FUNCTIONS_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/algorithms/detail/recalculate.hpp>
+#include <boost/geometry/policies/robustness/robust_point_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace section
+{
+
+template
+<
+ std::size_t Dimension,
+ typename Point,
+ typename RobustBox,
+ typename RobustPolicy
+>
+static inline bool preceding(int dir, Point const& point,
+ RobustBox const& robust_box,
+ RobustPolicy const& robust_policy)
+{
+ typename geometry::robust_point_type<Point, RobustPolicy>::type robust_point;
+ geometry::recalculate(robust_point, point, robust_policy);
+ return (dir == 1 && get<Dimension>(robust_point) < get<min_corner, Dimension>(robust_box))
+ || (dir == -1 && get<Dimension>(robust_point) > get<max_corner, Dimension>(robust_box));
+}
+
+template
+<
+ std::size_t Dimension,
+ typename Point,
+ typename RobustBox,
+ typename RobustPolicy
+>
+static inline bool exceeding(int dir, Point const& point,
+ RobustBox const& robust_box,
+ RobustPolicy const& robust_policy)
+{
+ typename geometry::robust_point_type<Point, RobustPolicy>::type robust_point;
+ geometry::recalculate(robust_point, point, robust_policy);
+ return (dir == 1 && get<Dimension>(robust_point) > get<max_corner, Dimension>(robust_box))
+ || (dir == -1 && get<Dimension>(robust_point) < get<min_corner, Dimension>(robust_box));
+}
+
+
+}} // namespace detail::section
+#endif
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_FUNCTIONS_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/sections/sectionalize.hpp b/3party/boost/boost/geometry/algorithms/detail/sections/sectionalize.hpp
index 250577c0c2..a744ea0a34 100644
--- a/3party/boost/boost/geometry/algorithms/detail/sections/sectionalize.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/sections/sectionalize.hpp
@@ -8,6 +8,9 @@
// This file was modified by Oracle on 2013, 2014.
// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,8 +18,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
@@ -25,7 +26,9 @@
#include <boost/concept/requires.hpp>
#include <boost/mpl/assert.hpp>
+#include <boost/mpl/vector_c.hpp>
#include <boost/range.hpp>
+#include <boost/static_assert.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/expand.hpp>
@@ -63,12 +66,15 @@ namespace boost { namespace geometry
\tparam DimensionCount number of dimensions for this section
\ingroup sectionalize
*/
-template <typename Box, std::size_t DimensionCount>
+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
+ static std::size_t const dimension_count = DimensionCount;
int directions[DimensionCount];
ring_identifier ring_id;
@@ -85,8 +91,7 @@ struct section
bool is_non_duplicate_last;
inline section()
- : id(-1)
- , begin_index(-1)
+ : begin_index(-1)
, end_index(-1)
, count(0)
, range_count(0)
@@ -122,75 +127,83 @@ struct sections : std::vector<section<Box, DimensionCount> >
namespace detail { namespace sectionalize
{
-template <std::size_t Dimension, std::size_t DimensionCount>
+template
+<
+ typename DimensionVector,
+ std::size_t Index,
+ std::size_t Count
+>
struct get_direction_loop
{
+ typedef typename boost::mpl::at_c<DimensionVector, Index>::type dimension;
+
template <typename Segment>
static inline void apply(Segment const& seg,
- int directions[DimensionCount])
+ int directions[Count])
{
typedef typename coordinate_type<Segment>::type coordinate_type;
+
coordinate_type const diff =
- geometry::get<1, Dimension>(seg) - geometry::get<0, Dimension>(seg);
+ geometry::get<1, dimension::value>(seg)
+ - geometry::get<0, dimension::value>(seg);
coordinate_type zero = coordinate_type();
- directions[Dimension] = diff > zero ? 1 : diff < zero ? -1 : 0;
+ directions[Index] = diff > zero ? 1 : diff < zero ? -1 : 0;
get_direction_loop
- <
- Dimension + 1, DimensionCount
- >::apply(seg, directions);
+ <
+ DimensionVector,
+ Index + 1,
+ Count
+ >::apply(seg, directions);
}
};
-template <std::size_t DimensionCount>
-struct get_direction_loop<DimensionCount, DimensionCount>
+template <typename DimensionVector, std::size_t Count>
+struct get_direction_loop<DimensionVector, Count, Count>
{
template <typename Segment>
- static inline void apply(Segment const&, int [DimensionCount])
+ static inline void apply(Segment const&, int [Count])
{}
};
-template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+//! Copy one static array to another
+template <typename T, std::size_t Index, std::size_t Count>
struct copy_loop
{
- static inline void apply(T const source[DimensionCount],
- T target[DimensionCount])
+ static inline void apply(T const source[Count], T target[Count])
{
- target[Dimension] = source[Dimension];
- copy_loop<T, Dimension + 1, DimensionCount>::apply(source, target);
+ target[Index] = source[Index];
+ copy_loop<T, Index + 1, Count>::apply(source, target);
}
};
-template <typename T, std::size_t DimensionCount>
-struct copy_loop<T, DimensionCount, DimensionCount>
+template <typename T, std::size_t Count>
+struct copy_loop<T, Count, Count>
{
- static inline void apply(T const [DimensionCount], T [DimensionCount])
+ static inline void apply(T const [Count], T [Count])
{}
};
-template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+//! Compare two static arrays
+template <typename T, std::size_t Index, std::size_t Count>
struct compare_loop
{
- static inline bool apply(T const source[DimensionCount],
- T const target[DimensionCount])
+ static inline bool apply(T const array1[Count], T const array2[Count])
{
- bool const not_equal = target[Dimension] != source[Dimension];
-
- return not_equal
+ return array1[Index] != array2[Index]
? false
: compare_loop
<
- T, Dimension + 1, DimensionCount
- >::apply(source, target);
+ T, Index + 1, Count
+ >::apply(array1, array2);
}
};
-template <typename T, std::size_t DimensionCount>
-struct compare_loop<T, DimensionCount, DimensionCount>
+template <typename T, std::size_t Count>
+struct compare_loop<T, Count, Count>
{
- static inline bool apply(T const [DimensionCount],
- T const [DimensionCount])
+ static inline bool apply(T const [Count], T const [Count])
{
return true;
@@ -215,9 +228,9 @@ struct check_duplicate_loop
}
return check_duplicate_loop
- <
+ <
Dimension + 1, DimensionCount
- >::apply(seg);
+ >::apply(seg);
}
};
@@ -231,20 +244,21 @@ struct check_duplicate_loop<DimensionCount, DimensionCount>
}
};
-template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+//! Assign a value to a static array
+template <typename T, std::size_t Index, std::size_t Count>
struct assign_loop
{
- static inline void apply(T dims[DimensionCount], int const value)
+ static inline void apply(T dims[Count], int const value)
{
- dims[Dimension] = value;
- assign_loop<T, Dimension + 1, DimensionCount>::apply(dims, value);
+ dims[Index] = value;
+ assign_loop<T, Index + 1, Count>::apply(dims, value);
}
};
-template <typename T, std::size_t DimensionCount>
-struct assign_loop<T, DimensionCount, DimensionCount>
+template <typename T, std::size_t Count>
+struct assign_loop<T, Count, Count>
{
- static inline void apply(T [DimensionCount], int const)
+ static inline void apply(T [Count], int const)
{
}
};
@@ -253,35 +267,42 @@ struct assign_loop<T, DimensionCount, DimensionCount>
template
<
typename Point,
- std::size_t DimensionCount
+ typename DimensionVector
>
struct sectionalize_part
{
+ static const std::size_t dimension_count
+ = boost::mpl::size<DimensionVector>::value;
+
template
<
- typename Range, // Can be closeable_view
+ typename Iterator,
typename RobustPolicy,
typename Sections
>
static inline void apply(Sections& sections,
- Range const& range,
+ Iterator begin, Iterator end,
RobustPolicy const& robust_policy,
- bool make_rescaled_boxes,
ring_identifier ring_id,
std::size_t max_count)
{
boost::ignore_unused_variable_warning(robust_policy);
- boost::ignore_unused_variable_warning(make_rescaled_boxes);
- typedef model::referring_segment<Point const> segment_type;
typedef typename boost::range_value<Sections>::type section_type;
- typedef model::segment
- <
- typename robust_point_type<Point, RobustPolicy>::type
- > robust_segment_type;
- typedef typename boost::range_iterator<Range const>::type iterator_type;
+ BOOST_STATIC_ASSERT
+ (
+ (static_cast<int>(section_type::dimension_count)
+ == static_cast<int>(boost::mpl::size<DimensionVector>::value))
+ );
- if ( boost::empty(range) )
+ typedef typename geometry::robust_point_type
+ <
+ Point,
+ RobustPolicy
+ >::type robust_point_type;
+
+ std::size_t const count = std::distance(begin, end);
+ if (count == 0)
{
return;
}
@@ -293,21 +314,24 @@ struct sectionalize_part
bool mark_first_non_duplicated = true;
std::size_t last_non_duplicate_index = sections.size();
- iterator_type it = boost::begin(range);
+ Iterator it = begin;
+ robust_point_type previous_robust_point;
+ geometry::recalculate(previous_robust_point, *it, robust_policy);
- for(iterator_type previous = it++;
- it != boost::end(range);
+ for(Iterator previous = it++;
+ it != end;
++previous, ++it, index++)
{
- segment_type segment(*previous, *it);
- robust_segment_type robust_segment;
- geometry::recalculate(robust_segment, segment, robust_policy);
+ robust_point_type current_robust_point;
+ geometry::recalculate(current_robust_point, *it, robust_policy);
+ model::referring_segment<robust_point_type> robust_segment(
+ previous_robust_point, current_robust_point);
- int direction_classes[DimensionCount] = {0};
+ int direction_classes[dimension_count] = {0};
get_direction_loop
- <
- 0, DimensionCount
- >::apply(robust_segment, direction_classes);
+ <
+ DimensionVector, 0, dimension_count
+ >::apply(robust_segment, direction_classes);
// if "dir" == 0 for all point-dimensions, it is duplicate.
// Those sections might be omitted, if wished, lateron
@@ -317,7 +341,7 @@ struct sectionalize_part
{
// Recheck because ALL dimensions should be checked,
// not only first one.
- // (DimensionCount might be < dimension<P>::value)
+ // (dimension_count might be < dimension<P>::value)
if (check_duplicate_loop
<
0, geometry::dimension<Point>::type::value
@@ -332,21 +356,20 @@ struct sectionalize_part
// Actual value is not important as long as it is not -1,0,1
assign_loop
<
- int, 0, DimensionCount
+ int, 0, dimension_count
>::apply(direction_classes, -99);
}
}
if (section.count > 0
- && (!compare_loop
+ && (! compare_loop
<
- int, 0, DimensionCount
+ int, 0, dimension_count
>::apply(direction_classes, section.directions)
- || section.count > max_count
- )
+ || section.count > max_count)
)
{
- if ( !section.duplicate )
+ if (! section.duplicate)
{
last_non_duplicate_index = sections.size();
}
@@ -361,9 +384,9 @@ struct sectionalize_part
section.ring_id = ring_id;
section.duplicate = duplicate;
section.non_duplicate_index = ndi;
- section.range_count = boost::size(range);
+ section.range_count = count;
- if ( mark_first_non_duplicated && !duplicate )
+ if (mark_first_non_duplicated && ! duplicate)
{
section.is_non_duplicate_first = true;
mark_first_non_duplicated = false;
@@ -371,25 +394,26 @@ struct sectionalize_part
copy_loop
<
- int, 0, DimensionCount
+ int, 0, dimension_count
>::apply(direction_classes, section.directions);
- expand_box(*previous, robust_policy, section);
+ geometry::expand(section.bounding_box, previous_robust_point);
}
- expand_box(*it, robust_policy, section);
+ geometry::expand(section.bounding_box, current_robust_point);
section.end_index = index + 1;
section.count++;
if (! duplicate)
{
ndi++;
}
+ previous_robust_point = current_robust_point;
}
// Add last section if applicable
if (section.count > 0)
{
- if ( !section.duplicate )
+ if (! section.duplicate)
{
last_non_duplicate_index = sections.size();
}
@@ -397,30 +421,21 @@ struct sectionalize_part
sections.push_back(section);
}
- if ( last_non_duplicate_index < sections.size()
- && !sections[last_non_duplicate_index].duplicate )
+ if (last_non_duplicate_index < sections.size()
+ && ! sections[last_non_duplicate_index].duplicate)
{
sections[last_non_duplicate_index].is_non_duplicate_last = true;
}
}
-
- template <typename InputPoint, typename RobustPolicy, typename Section>
- static inline void expand_box(InputPoint const& point,
- RobustPolicy const& robust_policy,
- Section& section)
- {
- typename geometry::point_type<typename Section::box_type>::type robust_point;
- geometry::recalculate(robust_point, point, robust_policy);
- geometry::expand(section.bounding_box, robust_point);
- }
};
template
<
- closure_selector Closure, bool Reverse,
+ closure_selector Closure,
+ bool Reverse,
typename Point,
- std::size_t DimensionCount
+ typename DimensionVector
>
struct sectionalize_range
{
@@ -432,13 +447,12 @@ struct sectionalize_range
>
static inline void apply(Range const& range,
RobustPolicy const& robust_policy,
- bool make_rescaled_boxes,
Sections& sections,
ring_identifier ring_id,
std::size_t max_count)
{
- typedef typename closeable_view<Range const, Closure>::type cview_type;
- typedef typename reversible_view
+ typedef typename closeable_view<Range const, Closure>::type cview_type;
+ typedef typename reversible_view
<
cview_type const,
Reverse ? iterate_reverse : iterate_forward
@@ -460,15 +474,16 @@ struct sectionalize_range
return;
}
- sectionalize_part<Point, DimensionCount>
- ::apply(sections, view, robust_policy, make_rescaled_boxes, ring_id, max_count);
+ sectionalize_part<Point, DimensionVector>::apply(sections,
+ boost::begin(view), boost::end(view),
+ robust_policy, ring_id, max_count);
}
};
template
<
bool Reverse,
- std::size_t DimensionCount
+ typename DimensionVector
>
struct sectionalize_polygon
{
@@ -480,20 +495,18 @@ struct sectionalize_polygon
>
static inline void apply(Polygon const& poly,
RobustPolicy const& robust_policy,
- bool make_rescaled_boxes,
Sections& sections,
ring_identifier ring_id, std::size_t max_count)
{
typedef typename point_type<Polygon>::type point_type;
- //typedef typename ring_type<Polygon>::type ring_type;
typedef sectionalize_range
- <
+ <
closure<Polygon>::value, Reverse,
- point_type, DimensionCount
- > per_range;
+ point_type, DimensionVector
+ > per_range;
ring_id.ring_index = -1;
- per_range::apply(exterior_ring(poly), robust_policy, make_rescaled_boxes, sections, ring_id, max_count);
+ per_range::apply(exterior_ring(poly), robust_policy, sections, ring_id, max_count);
ring_id.ring_index++;
typename interior_return_type<Polygon const>::type
@@ -501,15 +514,12 @@ struct sectionalize_polygon
for (typename detail::interior_iterator<Polygon const>::type
it = boost::begin(rings); it != boost::end(rings); ++it, ++ring_id.ring_index)
{
- per_range::apply(*it, robust_policy, make_rescaled_boxes, sections, ring_id, max_count);
+ per_range::apply(*it, robust_policy, sections, ring_id, max_count);
}
}
};
-template
-<
- std::size_t DimensionCount
->
+template <typename DimensionVector>
struct sectionalize_box
{
template
@@ -520,7 +530,6 @@ struct sectionalize_box
>
static inline void apply(Box const& box,
RobustPolicy const& robust_policy,
- bool make_rescaled_boxes,
Sections& sections,
ring_identifier const& ring_id, std::size_t max_count)
{
@@ -547,16 +556,16 @@ struct sectionalize_box
points.push_back(ll);
sectionalize_range
- <
+ <
closed, false,
- point_type,
- DimensionCount
- >::apply(points, robust_policy, make_rescaled_boxes, sections,
- ring_id, max_count);
+ point_type,
+ DimensionVector
+ >::apply(points, robust_policy, sections,
+ ring_id, max_count);
}
};
-template <std::size_t DimensionCount, typename Policy>
+template <typename DimensionVector, typename Policy>
struct sectionalize_multi
{
template
@@ -567,7 +576,6 @@ struct sectionalize_multi
>
static inline void apply(MultiGeometry const& multi,
RobustPolicy const& robust_policy,
- bool make_rescaled_boxes,
Sections& sections, ring_identifier ring_id, std::size_t max_count)
{
ring_id.multi_index = 0;
@@ -576,25 +584,12 @@ struct sectionalize_multi
it != boost::end(multi);
++it, ++ring_id.multi_index)
{
- Policy::apply(*it, robust_policy, make_rescaled_boxes, sections, ring_id, max_count);
+ Policy::apply(*it, robust_policy, sections, ring_id, max_count);
}
}
};
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++;
- }
-}
-
-template <typename Sections>
inline void enlarge_sections(Sections& sections)
{
// Robustness issue. Increase sections a tiny bit such that all points are really within (and not on border)
@@ -631,7 +626,7 @@ template
typename Tag,
typename Geometry,
bool Reverse,
- std::size_t DimensionCount
+ typename DimensionVector
>
struct sectionalize
{
@@ -646,29 +641,29 @@ template
<
typename Box,
bool Reverse,
- std::size_t DimensionCount
+ typename DimensionVector
>
-struct sectionalize<box_tag, Box, Reverse, DimensionCount>
- : detail::sectionalize::sectionalize_box<DimensionCount>
+struct sectionalize<box_tag, Box, Reverse, DimensionVector>
+ : detail::sectionalize::sectionalize_box<DimensionVector>
{};
template
<
typename LineString,
- std::size_t DimensionCount
+ typename DimensionVector
>
struct sectionalize
<
linestring_tag,
LineString,
false,
- DimensionCount
+ DimensionVector
>
: detail::sectionalize::sectionalize_range
<
closed, false,
typename point_type<LineString>::type,
- DimensionCount
+ DimensionVector
>
{};
@@ -676,14 +671,14 @@ template
<
typename Ring,
bool Reverse,
- std::size_t DimensionCount
+ typename DimensionVector
>
-struct sectionalize<ring_tag, Ring, Reverse, DimensionCount>
+struct sectionalize<ring_tag, Ring, Reverse, DimensionVector>
: detail::sectionalize::sectionalize_range
<
geometry::closure<Ring>::value, Reverse,
typename point_type<Ring>::type,
- DimensionCount
+ DimensionVector
>
{};
@@ -691,12 +686,12 @@ template
<
typename Polygon,
bool Reverse,
- std::size_t DimensionCount
+ typename DimensionVector
>
-struct sectionalize<polygon_tag, Polygon, Reverse, DimensionCount>
+struct sectionalize<polygon_tag, Polygon, Reverse, DimensionVector>
: detail::sectionalize::sectionalize_polygon
<
- Reverse, DimensionCount
+ Reverse, DimensionVector
>
{};
@@ -704,16 +699,16 @@ template
<
typename MultiPolygon,
bool Reverse,
- std::size_t DimensionCount
+ typename DimensionVector
>
-struct sectionalize<multi_polygon_tag, MultiPolygon, Reverse, DimensionCount>
+struct sectionalize<multi_polygon_tag, MultiPolygon, Reverse, DimensionVector>
: detail::sectionalize::sectionalize_multi
<
- DimensionCount,
+ DimensionVector,
detail::sectionalize::sectionalize_polygon
<
Reverse,
- DimensionCount
+ DimensionVector
>
>
@@ -723,17 +718,17 @@ template
<
typename MultiLinestring,
bool Reverse,
- std::size_t DimensionCount
+ typename DimensionVector
>
-struct sectionalize<multi_linestring_tag, MultiLinestring, Reverse, DimensionCount>
+struct sectionalize<multi_linestring_tag, MultiLinestring, Reverse, DimensionVector>
: detail::sectionalize::sectionalize_multi
<
- DimensionCount,
+ DimensionVector,
detail::sectionalize::sectionalize_range
<
closed, false,
typename point_type<MultiLinestring>::type,
- DimensionCount
+ DimensionVector
>
>
@@ -750,54 +745,61 @@ struct sectionalize<multi_linestring_tag, MultiLinestring, Reverse, DimensionCou
\tparam Sections type of sections to create
\param geometry geometry to create sections from
\param robust_policy policy to handle robustness issues
- \param enlarge_secion_boxes if true, boxes are enlarged a tiny bit to be sure
- they really contain all geometries (w.r.t. robustness)
\param sections structure with sections
\param source_index index to assign to the ring_identifiers
+ \param max_count maximal number of points per section
+ (defaults to 10, this seems to give the fastest results)
+
*/
-template<bool Reverse, typename Geometry, typename Sections, typename RobustPolicy>
+template
+<
+ bool Reverse,
+ typename DimensionVector,
+ typename Geometry,
+ typename Sections,
+ typename RobustPolicy
+>
inline void sectionalize(Geometry const& geometry,
RobustPolicy const& robust_policy,
- bool enlarge_secion_boxes,
Sections& sections,
- int source_index = 0)
+ int source_index = 0,
+ std::size_t max_count = 10)
{
concept::check<Geometry const>();
+ typedef typename boost::range_value<Sections>::type section_type;
+
+ // Compiletime check for point type of section boxes
+ // and point type related to robust policy
+ typedef typename geometry::coordinate_type
+ <
+ typename section_type::box_type
+ >::type ctype1;
+ typedef typename geometry::coordinate_type
+ <
+ typename geometry::robust_point_type
+ <
+ typename geometry::point_type<Geometry>::type,
+ RobustPolicy
+ >::type
+ >::type ctype2;
+
+ BOOST_MPL_ASSERT((boost::is_same<ctype1, ctype2>));
+
+
sections.clear();
ring_identifier ring_id;
ring_id.source_index = source_index;
- // A maximum of 10 segments per section seems to give the fastest results
dispatch::sectionalize
<
typename tag<Geometry>::type,
Geometry,
Reverse,
- Sections::value
- >::apply(geometry, robust_policy, enlarge_secion_boxes, sections, ring_id, 10);
-
- detail::sectionalize::set_section_unique_ids(sections);
- if (! enlarge_secion_boxes)
- {
- detail::sectionalize::enlarge_sections(sections);
- }
-}
-
-
-#if defined(BOOST_GEOMETRY_UNIT_TEST_SECTIONALIZE)
-// Backwards compatibility
-template<bool Reverse, typename Geometry, typename Sections>
-inline void sectionalize(Geometry const& geometry,
- Sections& sections,
- int source_index = 0)
-{
- return geometry::sectionalize<Reverse>(geometry, detail::no_rescale_policy(),
- false, sections,
- source_index);
+ DimensionVector
+ >::apply(geometry, robust_policy, sections, ring_id, max_count);
}
-#endif
}} // namespace boost::geometry
diff --git a/3party/boost/boost/geometry/algorithms/detail/signed_index_type.hpp b/3party/boost/boost/geometry/algorithms/detail/signed_index_type.hpp
new file mode 100644
index 0000000000..cff1e98edc
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/signed_index_type.hpp
@@ -0,0 +1,30 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_SIGNED_INDEX_TYPE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP
+
+
+#include <cstddef>
+#include <boost/type_traits/make_signed.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+typedef boost::make_signed<std::size_t>::type signed_index_type;
+typedef boost::make_signed<std::size_t>::type signed_size_type;
+//typedef std::ptrdiff_t signed_index_type;
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/single_geometry.hpp b/3party/boost/boost/geometry/algorithms/detail/single_geometry.hpp
index c65ff8bf84..31e4401099 100644
--- a/3party/boost/boost/geometry/algorithms/detail/single_geometry.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/single_geometry.hpp
@@ -14,7 +14,10 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SINGLE_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SINGLE_GEOMETRY_HPP
+#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_base_of.hpp>
+
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/util/range.hpp>
@@ -44,18 +47,14 @@ struct single_geometry
template <typename Geometry>
struct single_geometry<Geometry, true>
{
- typedef typename boost::mpl::if_c
- <
- boost::is_const<Geometry>::value,
- typename boost::range_value<Geometry>::type const&,
- typename boost::range_value<Geometry>::type
- >::type return_type;
+ typedef typename boost::range_reference<Geometry>::type return_type;
template <typename Id>
static inline return_type apply(Geometry & g, Id const& id)
{
- BOOST_ASSERT(id.multi_index >= 0);
- return range::at(g, id.multi_index);
+ BOOST_GEOMETRY_ASSERT(id.multi_index >= 0);
+ typedef typename boost::range_size<Geometry>::type size_type;
+ return range::at(g, static_cast<size_type>(id.multi_index));
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/sub_range.hpp b/3party/boost/boost/geometry/algorithms/detail/sub_range.hpp
index 5c5b2f9c04..29edc94e6c 100644
--- a/3party/boost/boost/geometry/algorithms/detail/sub_range.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/sub_range.hpp
@@ -14,6 +14,9 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
+#include <boost/mpl/if.hpp>
+
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry {
@@ -44,7 +47,7 @@ struct sub_range<Geometry, Tag, false>
template <typename Geometry>
struct sub_range<Geometry, polygon_tag, false>
{
- typedef typename geometry::ring_type<Geometry>::type & return_type;
+ typedef typename geometry::ring_return_type<Geometry>::type return_type;
template <typename Id> static inline
return_type apply(Geometry & geometry, Id const& id)
@@ -55,7 +58,11 @@ struct sub_range<Geometry, polygon_tag, false>
}
else
{
- std::size_t ri = static_cast<std::size_t>(id.ring_index);
+ typedef typename boost::range_size
+ <
+ typename geometry::interior_type<Geometry>::type
+ >::type size_type;
+ size_type const ri = static_cast<size_type>(id.ring_index);
return range::at(geometry::interior_rings(geometry), ri);
}
}
@@ -80,8 +87,10 @@ struct sub_range<Geometry, Tag, true>
template <typename Id> static inline
return_type apply(Geometry & geometry, Id const& id)
{
- BOOST_ASSERT(0 <= id.multi_index);
- return sub_sub_range::apply(range::at(geometry, id.multi_index), id);
+ BOOST_GEOMETRY_ASSERT(0 <= id.multi_index);
+ typedef typename boost::range_size<Geometry>::type size_type;
+ size_type const mi = static_cast<size_type>(id.multi_index);
+ return sub_sub_range::apply(range::at(geometry, mi), id);
}
};
@@ -103,7 +112,14 @@ typename sub_range_return_type<Geometry>::type
sub_range(Geometry & geometry, Id const& id)
{
return detail_dispatch::sub_range<Geometry>::apply(geometry, id);
-};
+}
+
+template <typename Geometry, typename Id> inline
+typename sub_range_return_type<Geometry const>::type
+sub_range(Geometry const& geometry, Id const& id)
+{
+ return detail_dispatch::sub_range<Geometry const>::apply(geometry, id);
+}
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
diff --git a/3party/boost/boost/geometry/algorithms/detail/sweep.hpp b/3party/boost/boost/geometry/algorithms/detail/sweep.hpp
new file mode 100644
index 0000000000..3dc78261f2
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/sweep.hpp
@@ -0,0 +1,87 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SWEEP_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SWEEP_HPP
+
+#include <boost/core/ignore_unused.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sweep
+{
+
+struct no_interrupt_policy
+{
+ static bool const enabled = false;
+
+ template <typename Event>
+ static inline bool apply(Event const&)
+ {
+ return false;
+ }
+};
+
+}} // namespace detail::sweep
+#endif // DOXYGEN_NO_DETAIL
+
+
+template
+<
+ typename Range,
+ typename PriorityQueue,
+ typename InitializationVisitor,
+ typename EventVisitor,
+ typename InterruptPolicy
+>
+inline void sweep(Range const& range, PriorityQueue& queue,
+ InitializationVisitor& initialization_visitor,
+ EventVisitor& event_visitor,
+ InterruptPolicy const& interrupt_policy)
+{
+ typedef typename PriorityQueue::value_type event_type;
+
+ initialization_visitor.apply(range, queue, event_visitor);
+ while (! queue.empty())
+ {
+ event_type event = queue.top();
+ queue.pop();
+ event_visitor.apply(event, queue);
+ if (interrupt_policy.enabled && interrupt_policy.apply(event))
+ {
+ break;
+ }
+ }
+
+ boost::ignore_unused(interrupt_policy);
+}
+
+
+template
+<
+ typename Range,
+ typename PriorityQueue,
+ typename InitializationVisitor,
+ typename EventVisitor
+>
+inline void sweep(Range const& range, PriorityQueue& queue,
+ InitializationVisitor& initialization_visitor,
+ EventVisitor& event_visitor)
+{
+ sweep(range, queue, initialization_visitor, event_visitor,
+ detail::sweep::no_interrupt_policy());
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SWEEP_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/thomas_inverse.hpp b/3party/boost/boost/geometry/algorithms/detail/thomas_inverse.hpp
new file mode 100644
index 0000000000..1027cd065c
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/thomas_inverse.hpp
@@ -0,0 +1,203 @@
+// Boost.Geometry
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_THOMAS_INVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_THOMAS_INVERSE_HPP
+
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+
+
+namespace boost { namespace geometry { namespace detail
+{
+
+/*!
+\brief The solution of the inverse problem of geodesics on latlong coordinates,
+ Forsyth-Andoyer-Lambert type approximation with second order terms.
+\author See
+ - Technical Report: PAUL D. THOMAS, MATHEMATICAL MODELS FOR NAVIGATION SYSTEMS, 1965
+ http://www.dtic.mil/docs/citations/AD0627893
+ - Technical Report: PAUL D. THOMAS, SPHEROIDAL GEODESICS, REFERENCE SYSTEMS, AND LOCAL GEOMETRY, 1970
+ http://www.dtic.mil/docs/citations/AD703541
+*/
+template <typename CT>
+class thomas_inverse
+{
+public:
+ template <typename T1, typename T2, typename Spheroid>
+ thomas_inverse(T1 const& lon1,
+ T1 const& lat1,
+ T2 const& lon2,
+ T2 const& lat2,
+ Spheroid const& spheroid)
+ : m_a(get_radius<0>(spheroid))
+ , m_f(detail::flattening<CT>(spheroid))
+ , m_is_result_zero(false)
+ {
+ // coordinates in radians
+
+ if ( math::equals(lon1, lon2)
+ && math::equals(lat1, lat2) )
+ {
+ m_is_result_zero = true;
+ return;
+ }
+
+ CT const one_minus_f = CT(1) - m_f;
+
+// CT const tan_theta1 = one_minus_f * tan(lat1);
+// CT const tan_theta2 = one_minus_f * tan(lat2);
+// CT const theta1 = atan(tan_theta1);
+// CT const theta2 = atan(tan_theta2);
+
+ CT const pi_half = math::pi<CT>() / CT(2);
+ CT const theta1 = math::equals(lat1, pi_half) ? lat1 :
+ math::equals(lat1, -pi_half) ? lat1 :
+ atan(one_minus_f * tan(lat1));
+ CT const theta2 = math::equals(lat2, pi_half) ? lat2 :
+ math::equals(lat2, -pi_half) ? lat2 :
+ atan(one_minus_f * tan(lat2));
+
+ CT const theta_m = (theta1 + theta2) / CT(2);
+ CT const d_theta_m = (theta2 - theta1) / CT(2);
+ m_d_lambda = lon2 - lon1;
+ CT const d_lambda_m = m_d_lambda / CT(2);
+
+ m_sin_theta_m = sin(theta_m);
+ m_cos_theta_m = cos(theta_m);
+ m_sin_d_theta_m = sin(d_theta_m);
+ m_cos_d_theta_m = cos(d_theta_m);
+ CT const sin2_theta_m = math::sqr(m_sin_theta_m);
+ CT const cos2_theta_m = math::sqr(m_cos_theta_m);
+ CT const sin2_d_theta_m = math::sqr(m_sin_d_theta_m);
+ CT const cos2_d_theta_m = math::sqr(m_cos_d_theta_m);
+ CT const sin_d_lambda_m = sin(d_lambda_m);
+ CT const sin2_d_lambda_m = math::sqr(sin_d_lambda_m);
+
+ CT const H = cos2_theta_m - sin2_d_theta_m;
+ CT const L = sin2_d_theta_m + H * sin2_d_lambda_m;
+ m_cos_d = CT(1) - CT(2) * L;
+ CT const d = acos(m_cos_d);
+ m_sin_d = sin(d);
+
+ CT const one_minus_L = CT(1) - L;
+
+ if ( math::equals(m_sin_d, CT(0))
+ || math::equals(L, CT(0))
+ || math::equals(one_minus_L, CT(0)) )
+ {
+ m_is_result_zero = true;
+ return;
+ }
+
+ CT const U = CT(2) * sin2_theta_m * cos2_d_theta_m / one_minus_L;
+ CT const V = CT(2) * sin2_d_theta_m * cos2_theta_m / L;
+ m_X = U + V;
+ m_Y = U - V;
+ m_T = d / m_sin_d;
+ //CT const D = CT(4) * math::sqr(T);
+ //CT const E = CT(2) * cos_d;
+ //CT const A = D * E;
+ //CT const B = CT(2) * D;
+ //CT const C = T - (A - E) / CT(2);
+ }
+
+ inline CT distance() const
+ {
+ if ( m_is_result_zero )
+ {
+ // TODO return some approximated value
+ return CT(0);
+ }
+
+ //CT const n1 = X * (A + C*X);
+ //CT const n2 = Y * (B + E*Y);
+ //CT const n3 = D*X*Y;
+
+ //CT const f_sqr = math::sqr(f);
+ //CT const f_sqr_per_64 = f_sqr / CT(64);
+
+ CT const delta1d = m_f * (m_T*m_X-m_Y) / CT(4);
+ //CT const delta2d = f_sqr_per_64 * (n1 - n2 + n3);
+
+ return m_a * m_sin_d * (m_T - delta1d);
+ //double S2 = a * sin_d * (T - delta1d + delta2d);
+ }
+
+ inline CT azimuth() const
+ {
+ // NOTE: if both cos_latX == 0 then below we'd have 0 * INF
+ // it's a situation when the endpoints are on the poles +-90 deg
+ // in this case the azimuth could either be 0 or +-pi
+ if ( m_is_result_zero )
+ {
+ return CT(0);
+ }
+
+ // may also be used to calculate distance21
+ //CT const D = CT(4) * math::sqr(T);
+ CT const E = CT(2) * m_cos_d;
+ //CT const A = D * E;
+ //CT const B = CT(2) * D;
+ // may also be used to calculate distance21
+ CT const f_sqr = math::sqr(m_f);
+ CT const f_sqr_per_64 = f_sqr / CT(64);
+
+ CT const F = CT(2)*m_Y-E*(CT(4)-m_X);
+ //CT const M = CT(32)*T-(CT(20)*T-A)*X-(B+CT(4))*Y;
+ CT const G = m_f*m_T/CT(2) + f_sqr_per_64;
+ CT const tan_d_lambda = tan(m_d_lambda);
+ CT const Q = -(F*G*tan_d_lambda) / CT(4);
+
+ CT const d_lambda_p = (m_d_lambda + Q) / CT(2);
+ CT const tan_d_lambda_p = tan(d_lambda_p);
+
+ CT const v = atan2(m_cos_d_theta_m, m_sin_theta_m * tan_d_lambda_p);
+ CT const u = atan2(-m_sin_d_theta_m, m_cos_theta_m * tan_d_lambda_p);
+
+ CT const pi = math::pi<CT>();
+ CT alpha1 = v + u;
+ if ( alpha1 > pi )
+ {
+ alpha1 -= CT(2) * pi;
+ }
+
+ return alpha1;
+ }
+
+private:
+ CT const m_a;
+ CT const m_f;
+
+ CT m_d_lambda;
+ CT m_cos_d;
+ CT m_sin_d;
+ CT m_X;
+ CT m_Y;
+ CT m_T;
+ CT m_sin_theta_m;
+ CT m_cos_theta_m;
+ CT m_sin_d_theta_m;
+ CT m_cos_d_theta_m;
+
+ bool m_is_result_zero;
+};
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_THOMAS_INVERSE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/throw_on_empty_input.hpp b/3party/boost/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
index 3d83e6930e..2f82e1a8bd 100644
--- a/3party/boost/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,7 +17,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP
#include <boost/geometry/core/exception.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
// BSG 2012-02-06: we use this currently only for distance.
// For other scalar results area,length,perimeter it is commented on purpose.
@@ -24,6 +29,10 @@
// So decided that at least for Boost 1.49 this is commented for
// scalar results, except distance.
+#if defined(BOOST_GEOMETRY_EMPTY_INPUT_NO_THROW)
+#include <boost/core/ignore_unused.hpp>
+#endif
+
namespace boost { namespace geometry
{
@@ -35,10 +44,12 @@ 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)
+ if (geometry::is_empty(geometry))
{
throw empty_input_exception();
}
+#else
+ boost::ignore_unused(geometry);
#endif
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/turns/compare_turns.hpp b/3party/boost/boost/geometry/algorithms/detail/turns/compare_turns.hpp
index 7e21c654eb..c29d5863b7 100644
--- a/3party/boost/boost/geometry/algorithms/detail/turns/compare_turns.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/turns/compare_turns.hpp
@@ -30,13 +30,14 @@ namespace detail { namespace turns
// seg_id -> fraction -> other_id -> operation
template
<
- typename IdLess = std::less<int>,
+ typename IdLess = std::less<signed_index_type>,
int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0,
std::size_t OpId = 0
>
struct less_seg_fraction_other_op
{
BOOST_STATIC_ASSERT(OpId < 2);
+ static const std::size_t other_op_id = (OpId + 1) % 2;
template <typename Op>
static inline int order_op(Op const& op)
@@ -59,30 +60,33 @@ struct less_seg_fraction_other_op
return order_op(left) < order_op(right);
}
- template <typename Op>
- static inline bool use_other_id(Op const& left, Op const& right)
+ template <typename Turn>
+ static inline bool use_other_id(Turn const& left, Turn const& right)
{
- if ( left.other_id.multi_index != right.other_id.multi_index )
+ segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id;
+ segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id;
+
+ if ( left_other_seg_id.multi_index != right_other_seg_id.multi_index )
{
- return left.other_id.multi_index < right.other_id.multi_index;
+ return left_other_seg_id.multi_index < right_other_seg_id.multi_index;
}
- if ( left.other_id.ring_index != right.other_id.ring_index )
+ if ( left_other_seg_id.ring_index != right_other_seg_id.ring_index )
{
- return left.other_id.ring_index != right.other_id.ring_index;
+ return left_other_seg_id.ring_index != right_other_seg_id.ring_index;
}
- if ( left.other_id.segment_index != right.other_id.segment_index )
+ if ( left_other_seg_id.segment_index != right_other_seg_id.segment_index )
{
- return IdLess()(left.other_id.segment_index,
- right.other_id.segment_index);
+ return IdLess()(left_other_seg_id.segment_index,
+ right_other_seg_id.segment_index);
}
- return use_operation(left, right);
+ return use_operation(left.operations[OpId], right.operations[OpId]);
}
- template <typename Op>
- static inline bool use_fraction(Op const& left, Op const& right)
+ template <typename Turn>
+ static inline bool use_fraction(Turn const& left, Turn const& right)
{
- return left.fraction < right.fraction
- || ( geometry::math::equals(left.fraction, right.fraction)
+ return left.operations[OpId].fraction < right.operations[OpId].fraction
+ || ( geometry::math::equals(left.operations[OpId].fraction, right.operations[OpId].fraction)
&& use_other_id(left, right)
);
}
@@ -93,7 +97,7 @@ struct less_seg_fraction_other_op
segment_identifier const& sl = left.operations[OpId].seg_id;
segment_identifier const& sr = right.operations[OpId].seg_id;
- return sl < sr || ( sl == sr && use_fraction(left.operations[OpId], right.operations[OpId]) );
+ return sl < sr || ( sl == sr && use_fraction(left, right) );
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/turns/debug_turn.hpp b/3party/boost/boost/geometry/algorithms/detail/turns/debug_turn.hpp
index 910324c5ed..5c4f03277a 100644
--- a/3party/boost/boost/geometry/algorithms/detail/turns/debug_turn.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/turns/debug_turn.hpp
@@ -14,8 +14,10 @@
#include <iostream>
#include <string>
-#include <boost/geometry/io/wkt/write.hpp>
#include <boost/algorithm/string/predicate.hpp>
+
+#include <boost/geometry/io/wkt/write.hpp>
+#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
#endif // BOOST_GEOMETRY_DEBUG_TURNS
diff --git a/3party/boost/boost/geometry/algorithms/detail/turns/print_turns.hpp b/3party/boost/boost/geometry/algorithms/detail/turns/print_turns.hpp
index 8b42a0ce96..9d4e45c41f 100644
--- a/3party/boost/boost/geometry/algorithms/detail/turns/print_turns.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/turns/print_turns.hpp
@@ -10,9 +10,9 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_TURNS_PRINT_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_TURNS_PRINT_TURNS_HPP
+#include <algorithm>
#include <iostream>
-#include <boost/foreach.hpp>
#include <boost/range.hpp>
#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
@@ -27,21 +27,16 @@ namespace boost { namespace geometry
namespace detail { namespace turns
{
-
-
-template <typename Geometry1, typename Geometry2, typename Turns>
-static inline void print_turns(Geometry1 const& g1,
- Geometry2 const& g2,
- Turns const& turns)
+struct turn_printer
{
- typedef typename boost::range_value<Turns>::type turn_info;
+ turn_printer(std::ostream & os)
+ : index(0)
+ , out(os)
+ {}
- std::cout << geometry::wkt(g1) << std::endl;
- std::cout << geometry::wkt(g2) << std::endl;
- int index = 0;
- BOOST_FOREACH(turn_info const& turn, turns)
+ template <typename Turn>
+ void operator()(Turn const& turn)
{
- std::ostream& out = std::cout;
out << index
<< ": " << geometry::method_char(turn.method);
@@ -62,10 +57,6 @@ static inline void print_turns(Geometry1 const& g1,
<< ", m: " << turn.operations[0].seg_id.multi_index
<< ", r: " << turn.operations[0].seg_id.ring_index
<< ", s: " << turn.operations[0].seg_id.segment_index << ", ";
- out << "other: " << turn.operations[0].other_id.source_index
- << ", m: " << turn.operations[0].other_id.multi_index
- << ", r: " << turn.operations[0].other_id.ring_index
- << ", s: " << turn.operations[0].other_id.segment_index;
out << ", fr: " << fraction[0];
out << ", col?: " << turn.operations[0].is_collinear;
out << ' ' << geometry::dsv(turn.point) << ' ';
@@ -80,17 +71,27 @@ static inline void print_turns(Geometry1 const& g1,
<< ", m: " << turn.operations[1].seg_id.multi_index
<< ", r: " << turn.operations[1].seg_id.ring_index
<< ", s: " << turn.operations[1].seg_id.segment_index << ", ";
- out << "other: " << turn.operations[1].other_id.source_index
- << ", m: " << turn.operations[1].other_id.multi_index
- << ", r: " << turn.operations[1].other_id.ring_index
- << ", s: " << turn.operations[1].other_id.segment_index;
out << ", fr: " << fraction[1];
out << ", col?: " << turn.operations[1].is_collinear;
out << ' ' << geometry::dsv(turn.point) << ' ';
++index;
- std::cout << std::endl;
+ out << std::endl;
}
+
+ int index;
+ std::ostream & out;
+};
+
+template <typename Geometry1, typename Geometry2, typename Turns>
+static inline void print_turns(Geometry1 const& g1,
+ Geometry2 const& g2,
+ Turns const& turns)
+{
+ std::cout << geometry::wkt(g1) << std::endl;
+ std::cout << geometry::wkt(g2) << std::endl;
+
+ std::for_each(boost::begin(turns), boost::end(turns), turn_printer(std::cout));
}
diff --git a/3party/boost/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp b/3party/boost/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp
index d48736c8f5..ccb19efb73 100644
--- a/3party/boost/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp
@@ -39,7 +39,7 @@ private:
{
return geometry::equals(t1.point, t2.point)
&& t1.operations[0].seg_id == t2.operations[0].seg_id
- && t1.operations[0].other_id == t2.operations[0].other_id;
+ && t1.operations[1].seg_id == t2.operations[1].seg_id;
}
};
diff --git a/3party/boost/boost/geometry/algorithms/detail/vincenty_direct.hpp b/3party/boost/boost/geometry/algorithms/detail/vincenty_direct.hpp
new file mode 100644
index 0000000000..775687cfdb
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/vincenty_direct.hpp
@@ -0,0 +1,190 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_VINCENTY_DIRECT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_VINCENTY_DIRECT_HPP
+
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+
+
+#ifndef BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS
+#define BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS 1000
+#endif
+
+
+namespace boost { namespace geometry { namespace detail
+{
+
+/*!
+\brief The solution of the direct problem of geodesics on latlong coordinates, after Vincenty, 1975
+\author See
+ - http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
+ - http://www.icsm.gov.au/gda/gdav2.3.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 CT>
+class vincenty_direct
+{
+public:
+ template <typename T, typename Dist, typename Azi, typename Spheroid>
+ vincenty_direct(T const& lo1,
+ T const& la1,
+ Dist const& distance,
+ Azi const& azimuth12,
+ Spheroid const& spheroid)
+ : lon1(lo1)
+ , lat1(la1)
+ , is_distance_zero(false)
+ {
+ if ( math::equals(distance, Dist(0)) || distance < Dist(0) )
+ {
+ is_distance_zero = true;
+ return;
+ }
+
+ CT const radius_a = CT(get_radius<0>(spheroid));
+ CT const radius_b = CT(get_radius<2>(spheroid));
+ flattening = geometry::detail::flattening<CT>(spheroid);
+
+ sin_azimuth12 = sin(azimuth12);
+ cos_azimuth12 = cos(azimuth12);
+
+ // U: reduced latitude, defined by tan U = (1-f) tan phi
+ one_min_f = CT(1) - flattening;
+ CT const tan_U1 = one_min_f * tan(lat1);
+ CT const sigma1 = atan2(tan_U1, cos_azimuth12); // (1)
+
+ // may be calculated from tan using 1 sqrt()
+ CT const U1 = atan(tan_U1);
+ sin_U1 = sin(U1);
+ cos_U1 = cos(U1);
+
+ sin_alpha = cos_U1 * sin_azimuth12; // (2)
+ sin_alpha_sqr = math::sqr(sin_alpha);
+ cos_alpha_sqr = CT(1) - sin_alpha_sqr;
+
+ CT const b_sqr = radius_b * radius_b;
+ CT const u_sqr = cos_alpha_sqr * (radius_a * radius_a - b_sqr) / b_sqr;
+ CT const A = CT(1) + (u_sqr/CT(16384)) * (CT(4096) + u_sqr*(CT(-768) + u_sqr*(CT(320) - u_sqr*CT(175)))); // (3)
+ CT const B = (u_sqr/CT(1024))*(CT(256) + u_sqr*(CT(-128) + u_sqr*(CT(74) - u_sqr*CT(47)))); // (4)
+
+ CT s_div_bA = distance / (radius_b * A);
+ sigma = s_div_bA; // (7)
+
+ CT previous_sigma;
+
+ int counter = 0; // robustness
+
+ do
+ {
+ previous_sigma = sigma;
+
+ CT const two_sigma_m = CT(2) * sigma1 + sigma; // (5)
+
+ sin_sigma = sin(sigma);
+ cos_sigma = cos(sigma);
+ CT const sin_sigma_sqr = math::sqr(sin_sigma);
+ cos_2sigma_m = cos(two_sigma_m);
+ cos_2sigma_m_sqr = math::sqr(cos_2sigma_m);
+
+ CT const delta_sigma = B * sin_sigma * (cos_2sigma_m
+ + (B/CT(4)) * ( cos_sigma * (CT(-1) + CT(2)*cos_2sigma_m_sqr)
+ - (B/CT(6) * cos_2sigma_m * (CT(-3)+CT(4)*sin_sigma_sqr) * (CT(-3)+CT(4)*cos_2sigma_m_sqr)) )); // (6)
+
+ sigma = s_div_bA + delta_sigma; // (7)
+
+ ++counter; // robustness
+
+ } while ( geometry::math::abs(previous_sigma - sigma) > CT(1e-12)
+ //&& geometry::math::abs(sigma) < pi
+ && counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness
+ }
+
+ inline CT lat2() const
+ {
+ if ( is_distance_zero )
+ {
+ return lat1;
+ }
+
+ return atan2( sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_azimuth12,
+ one_min_f * math::sqrt(sin_alpha_sqr + math::sqr(sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_azimuth12))); // (8)
+ }
+
+ inline CT lon2() const
+ {
+ if ( is_distance_zero )
+ {
+ return lon1;
+ }
+
+ CT const lambda = atan2( sin_sigma * sin_azimuth12,
+ cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_azimuth12); // (9)
+ CT const C = (flattening/CT(16)) * cos_alpha_sqr * ( CT(4) + flattening * ( CT(4) - CT(3) * cos_alpha_sqr ) ); // (10)
+ CT const L = lambda - (CT(1) - C) * flattening * sin_alpha
+ * ( sigma + C * sin_sigma * ( cos_2sigma_m + C * cos_sigma * ( CT(-1) + CT(2) * cos_2sigma_m_sqr ) ) ); // (11)
+
+ return lon1 + L;
+ }
+
+ inline CT azimuth21() const
+ {
+ // NOTE: signs of X and Y are different than in the original paper
+ return is_distance_zero ?
+ CT(0) :
+ atan2(-sin_alpha, sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_azimuth12); // (12)
+ }
+
+private:
+ CT sigma;
+ CT sin_sigma;
+ CT cos_sigma;
+
+ CT cos_2sigma_m;
+ CT cos_2sigma_m_sqr;
+
+ CT sin_alpha;
+ CT sin_alpha_sqr;
+ CT cos_alpha_sqr;
+
+ CT sin_azimuth12;
+ CT cos_azimuth12;
+
+ CT sin_U1;
+ CT cos_U1;
+
+ CT flattening;
+ CT one_min_f;
+
+ CT const lon1;
+ CT const lat1;
+
+ bool is_distance_zero;
+};
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_VINCENTY_DIRECT_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/vincenty_inverse.hpp b/3party/boost/boost/geometry/algorithms/detail/vincenty_inverse.hpp
new file mode 100644
index 0000000000..0b07fa18a1
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/detail/vincenty_inverse.hpp
@@ -0,0 +1,218 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_VINCENTY_INVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_VINCENTY_INVERSE_HPP
+
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+
+
+#ifndef BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS
+#define BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS 1000
+#endif
+
+
+namespace boost { namespace geometry { namespace detail
+{
+
+/*!
+\brief The solution of the inverse problem of geodesics on latlong coordinates, after Vincenty, 1975
+\author See
+ - http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
+ - http://www.icsm.gov.au/gda/gdav2.3.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 CT>
+class vincenty_inverse
+{
+public:
+ template <typename T1, typename T2, typename Spheroid>
+ vincenty_inverse(T1 const& lon1,
+ T1 const& lat1,
+ T2 const& lon2,
+ T2 const& lat2,
+ Spheroid const& spheroid)
+ : is_result_zero(false)
+ {
+ if (math::equals(lat1, lat2) && math::equals(lon1, lon2))
+ {
+ is_result_zero = true;
+ return;
+ }
+
+ CT const c1 = 1;
+ CT const c2 = 2;
+ CT const c3 = 3;
+ CT const c4 = 4;
+ CT const c16 = 16;
+ CT const c_e_12 = CT(1e-12);
+
+ CT const pi = geometry::math::pi<CT>();
+ CT const two_pi = c2 * pi;
+
+ // lambda: difference in longitude on an auxiliary sphere
+ CT L = lon2 - lon1;
+ CT lambda = L;
+
+ if (L < -pi) L += two_pi;
+ if (L > pi) L -= two_pi;
+
+ radius_a = CT(get_radius<0>(spheroid));
+ radius_b = CT(get_radius<2>(spheroid));
+ CT const flattening = geometry::detail::flattening<CT>(spheroid);
+
+ // U: reduced latitude, defined by tan U = (1-f) tan phi
+ CT const one_min_f = c1 - flattening;
+ CT const tan_U1 = one_min_f * tan(lat1); // above (1)
+ CT const tan_U2 = one_min_f * tan(lat2); // above (1)
+
+ // calculate sin U and cos U using trigonometric identities
+ CT const temp_den_U1 = math::sqrt(c1 + math::sqr(tan_U1));
+ CT const temp_den_U2 = math::sqrt(c1 + math::sqr(tan_U2));
+ // cos = 1 / sqrt(1 + tan^2)
+ cos_U1 = c1 / temp_den_U1;
+ cos_U2 = c1 / temp_den_U2;
+ // sin = tan / sqrt(1 + tan^2)
+ sin_U1 = tan_U1 / temp_den_U1;
+ sin_U2 = tan_U2 / temp_den_U2;
+
+ // calculate sin U and cos U directly
+ //CT const U1 = atan(tan_U1);
+ //CT const U2 = atan(tan_U2);
+ //cos_U1 = cos(U1);
+ //cos_U2 = cos(U2);
+ //sin_U1 = tan_U1 * cos_U1; // sin(U1);
+ //sin_U2 = tan_U2 * cos_U2; // sin(U2);
+
+ CT previous_lambda;
+
+ int counter = 0; // robustness
+
+ do
+ {
+ previous_lambda = lambda; // (13)
+ sin_lambda = sin(lambda);
+ cos_lambda = cos(lambda);
+ sin_sigma = math::sqrt(math::sqr(cos_U2 * sin_lambda) + math::sqr(cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda)); // (14)
+ CT 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)
+
+ CT C = flattening/c16 * cos2_alpha * (c4 + flattening * (c4 - c3 * cos2_alpha)); // (10)
+ sigma = atan2(sin_sigma, cos_sigma); // (16)
+ lambda = L + (c1 - C) * flattening * sin_alpha *
+ (sigma + C * sin_sigma * ( cos2_sigma_m + C * cos_sigma * (-c1 + c2 * math::sqr(cos2_sigma_m)))); // (11)
+
+ ++counter; // robustness
+
+ } while ( geometry::math::abs(previous_lambda - lambda) > c_e_12
+ && geometry::math::abs(lambda) < pi
+ && counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness
+ }
+
+ inline CT distance() const
+ {
+ if ( is_result_zero )
+ {
+ return CT(0);
+ }
+
+ // Oops getting hard here
+ // (again, problem is that ttmath cannot divide by doubles, which is OK)
+ CT const c1 = 1;
+ CT const c2 = 2;
+ CT const c3 = 3;
+ CT const c4 = 4;
+ CT const c6 = 6;
+ CT const c47 = 47;
+ CT const c74 = 74;
+ CT const c128 = 128;
+ CT const c256 = 256;
+ CT const c175 = 175;
+ CT const c320 = 320;
+ CT const c768 = 768;
+ CT const c1024 = 1024;
+ CT const c4096 = 4096;
+ CT const c16384 = 16384;
+
+ //CT sqr_u = cos2_alpha * (math::sqr(radius_a) - math::sqr(radius_b)) / math::sqr(radius_b); // above (1)
+ CT sqr_u = cos2_alpha * ( math::sqr(radius_a / radius_b) - c1 ); // above (1)
+
+ CT A = c1 + sqr_u/c16384 * (c4096 + sqr_u * (-c768 + sqr_u * (c320 - c175 * sqr_u))); // (3)
+ CT B = sqr_u/c1024 * (c256 + sqr_u * ( -c128 + sqr_u * (c74 - c47 * sqr_u))); // (4)
+ CT 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 radius_b * A * (sigma - delta_sigma); // (19)
+ }
+
+ inline CT azimuth() const
+ {
+ return is_result_zero ?
+ CT(0) :
+ atan2(cos_U2 * sin_lambda, cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda); // (20)
+ }
+
+// inline CT azimuth21() const
+// {
+// // NOTE: signs of X and Y are different than in the original paper
+// return is_result_zero ?
+// CT(0) :
+// atan2(-cos_U1 * sin_lambda, sin_U1 * cos_U2 - cos_U1 * sin_U2 * cos_lambda); // (21)
+// }
+
+private:
+ // alpha: azimuth of the geodesic at the equator
+ CT cos2_alpha;
+ CT 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
+ CT sigma;
+ CT sin_sigma;
+ CT cos2_sigma_m;
+
+ CT sin_lambda;
+ CT cos_lambda;
+
+ // set only once
+ CT cos_U1;
+ CT cos_U2;
+ CT sin_U1;
+ CT sin_U2;
+
+ // set only once
+ CT radius_a;
+ CT radius_b;
+
+ bool is_result_zero;
+};
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_VINCENTY_INVERSE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/detail/within/point_in_geometry.hpp b/3party/boost/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
index 6f1c1816cb..68e74a8c5c 100644
--- a/3party/boost/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
+++ b/3party/boost/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -20,12 +20,15 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP
-#include <boost/assert.hpp>
+
+#include <boost/core/ignore_unused.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
@@ -35,6 +38,7 @@
#include <boost/geometry/strategies/within.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/detail/normalized_view.hpp>
namespace boost { namespace geometry {
@@ -51,14 +55,14 @@ inline int check_result_type(int result)
template <typename T>
inline T check_result_type(T result)
{
- BOOST_ASSERT(false);
+ BOOST_GEOMETRY_ASSERT(false);
return result;
}
template <typename Point, typename Range, typename Strategy> inline
int point_in_range(Point const& point, Range const& range, Strategy const& strategy)
{
- boost::ignore_unused_variable_warning(strategy);
+ boost::ignore_unused(strategy);
typedef typename boost::range_iterator<Range const>::type iterator_type;
typename Strategy::state_type state;
@@ -147,7 +151,7 @@ struct point_in_geometry<Point2, point_tag>
template <typename Point1, typename Strategy> static inline
int apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
{
- boost::ignore_unused_variable_warning(strategy);
+ boost::ignore_unused(strategy);
return strategy.apply(point1, point2) ? 1 : -1;
}
};
@@ -158,6 +162,8 @@ struct point_in_geometry<Segment, segment_tag>
template <typename Point, typename Strategy> static inline
int apply(Point const& point, Segment const& segment, Strategy const& strategy)
{
+ boost::ignore_unused(strategy);
+
typedef typename geometry::point_type<Segment>::type point_type;
point_type p0, p1;
// TODO: don't copy points
@@ -194,11 +200,11 @@ struct point_in_geometry<Linestring, linestring_tag>
return -1; // exterior
// if the linestring doesn't have a boundary
- if ( detail::equals::equals_point_point(*boost::begin(linestring), *(--boost::end(linestring))) )
+ if (detail::equals::equals_point_point(range::front(linestring), range::back(linestring)))
return 1; // interior
// else if the point is equal to the one of the terminal points
- else if ( detail::equals::equals_point_point(point, *boost::begin(linestring))
- || detail::equals::equals_point_point(point, *(--boost::end(linestring))) )
+ else if (detail::equals::equals_point_point(point, range::front(linestring))
+ || detail::equals::equals_point_point(point, range::back(linestring)))
return 0; // boundary
else
return 1; // interior
@@ -207,7 +213,7 @@ struct point_in_geometry<Linestring, linestring_tag>
// throw an exception here?
/*else if ( count == 1 )
{
- if ( detail::equals::equals_point_point(point, *boost::begin(linestring)) )
+ if ( detail::equals::equals_point_point(point, range::front(linestring)) )
return 1;
}*/
@@ -287,7 +293,7 @@ struct point_in_geometry<Geometry, multi_point_tag>
{
int pip = point_in_geometry<point_type>::apply(point, *it, strategy);
- //BOOST_ASSERT(pip != 0);
+ //BOOST_GEOMETRY_ASSERT(pip != 0);
if ( pip > 0 ) // inside
return 1;
}
@@ -333,8 +339,8 @@ struct point_in_geometry<Geometry, multi_linestring_tag>
if ( boost::size(*it) < 2 )
continue;
- point_type const& front = *boost::begin(*it);
- point_type const& back = *(--boost::end(*it));
+ point_type const& front = range::front(*it);
+ point_type const& back = range::back(*it);
// is closed_ring - no boundary
if ( detail::equals::equals_point_point(front, back) )
diff --git a/3party/boost/boost/geometry/algorithms/dispatch/distance.hpp b/3party/boost/boost/geometry/algorithms/dispatch/distance.hpp
index 58fd59340e..cae3ebd0c9 100644
--- a/3party/boost/boost/geometry/algorithms/dispatch/distance.hpp
+++ b/3party/boost/boost/geometry/algorithms/dispatch/distance.hpp
@@ -22,7 +22,9 @@
#include <boost/geometry/core/reverse_dispatch.hpp>
+#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tag_cast.hpp>
+#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
@@ -36,16 +38,33 @@ 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,
+ typename Strategy = typename detail::distance::default_strategy
+ <
+ Geometry1, Geometry2
+ >::type,
+ typename Tag1 = typename tag_cast
+ <
+ typename tag<Geometry1>::type,
+ segment_tag,
+ box_tag,
+ linear_tag,
+ areal_tag
+ >::type,
+ typename Tag2 = typename tag_cast
+ <
+ typename tag<Geometry2>::type,
+ segment_tag,
+ box_tag,
+ linear_tag,
+ areal_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>
@@ -53,8 +72,6 @@ struct distance: not_implemented<Tag1, Tag2>
-
-
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/3party/boost/boost/geometry/algorithms/dispatch/envelope.hpp b/3party/boost/boost/geometry/algorithms/dispatch/envelope.hpp
new file mode 100644
index 0000000000..8b1324d72e
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/dispatch/envelope.hpp
@@ -0,0 +1,49 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_DISPATCH_ENVELOPE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DISPATCH_ENVELOPE_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry,
+ typename Tag = typename tag<Geometry>::type,
+ typename CSTag = typename cs_tag<Geometry>::type
+>
+struct envelope : not_implemented<Tag>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DISPATCH_ENVELOPE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/dispatch/expand.hpp b/3party/boost/boost/geometry/algorithms/dispatch/expand.hpp
new file mode 100644
index 0000000000..e290080ac0
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/dispatch/expand.hpp
@@ -0,0 +1,58 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_DISPATCH_EXPAND_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DISPATCH_EXPAND_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryOut, typename Geometry,
+ typename StrategyLess = strategy::compare::default_strategy,
+ typename StrategyGreater = strategy::compare::default_strategy,
+ typename TagOut = typename tag<GeometryOut>::type,
+ typename Tag = typename tag<Geometry>::type,
+ typename CSTagOut = typename cs_tag<GeometryOut>::type,
+ typename CSTag = typename cs_tag<Geometry>::type
+>
+struct expand : not_implemented<TagOut, Tag>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DISPATCH_EXPAND_HPP
diff --git a/3party/boost/boost/geometry/algorithms/dispatch/is_valid.hpp b/3party/boost/boost/geometry/algorithms/dispatch/is_valid.hpp
index 266bab9181..5d8108655c 100644
--- a/3party/boost/boost/geometry/algorithms/dispatch/is_valid.hpp
+++ b/3party/boost/boost/geometry/algorithms/dispatch/is_valid.hpp
@@ -27,10 +27,8 @@ template
<
typename Geometry,
typename Tag = typename tag<Geometry>::type,
- // for linear geometries: determines if spikes are allowed
- bool AllowSpikes = true,
- // for areal geometries: determines if duplicate points are allowed
- bool AllowDuplicates = true
+ // for multi-geometries: determines if empty multi-geometries are allowed
+ bool AllowEmptyMultiGeometries = true
>
struct is_valid
: not_implemented<Geometry>
diff --git a/3party/boost/boost/geometry/algorithms/envelope.hpp b/3party/boost/boost/geometry/algorithms/envelope.hpp
index e06ed71e81..2f5c7430b4 100644
--- a/3party/boost/boost/geometry/algorithms/envelope.hpp
+++ b/3party/boost/boost/geometry/algorithms/envelope.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -14,281 +19,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
-#include <vector>
-
-#include <boost/numeric/conversion/cast.hpp>
-#include <boost/range.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/variant/apply_visitor.hpp>
-#include <boost/variant/variant_fwd.hpp>
-
-#include <boost/geometry/algorithms/assign.hpp>
-#include <boost/geometry/algorithms/expand.hpp>
-#include <boost/geometry/algorithms/not_implemented.hpp>
-#include <boost/geometry/core/cs.hpp>
-#include <boost/geometry/core/exterior_ring.hpp>
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/tags.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
-struct envelope_expand_one
-{
- template<typename Geometry, typename Box>
- 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
-struct envelope_range
-{
- /// Calculate envelope of range using a strategy
- template <typename Range, typename Box>
- static inline void apply(Range const& range, Box& mbr)
- {
- assign_inverse(mbr);
- envelope_range_additional(range, mbr);
- }
-};
-
-
-struct envelope_multi_linestring
-{
- template<typename MultiLinestring, typename Box>
- 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
-struct envelope_multi_polygon
-{
- template<typename MultiPolygon, typename Box>
- 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 // DOXYGEN_NO_DETAIL
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-template
-<
- typename Geometry,
- typename Tag = typename tag<Geometry>::type
->
-struct envelope: not_implemented<Tag>
-{};
-
-
-template <typename Point>
-struct envelope<Point, point_tag>
- : detail::envelope::envelope_expand_one
-{};
-
-
-template <typename Box>
-struct envelope<Box, box_tag>
- : detail::envelope::envelope_expand_one
-{};
-
-
-template <typename Segment>
-struct envelope<Segment, segment_tag>
- : detail::envelope::envelope_expand_one
-{};
-
-
-template <typename Linestring>
-struct envelope<Linestring, linestring_tag>
- : detail::envelope::envelope_range
-{};
-
-
-template <typename Ring>
-struct envelope<Ring, ring_tag>
- : detail::envelope::envelope_range
-{};
-
-
-template <typename Polygon>
-struct envelope<Polygon, polygon_tag>
- : detail::envelope::envelope_range
-{
- template <typename Box>
- static inline void apply(Polygon const& poly, Box& mbr)
- {
- // For polygon, inspecting outer ring is sufficient
- detail::envelope::envelope_range::apply(exterior_ring(poly), mbr);
- }
-
-};
-
-
-template <typename Multi>
-struct envelope<Multi, multi_point_tag>
- : detail::envelope::envelope_range
-{};
-
-
-template <typename Multi>
-struct envelope<Multi, multi_linestring_tag>
- : detail::envelope::envelope_multi_linestring
-{};
-
-
-template <typename Multi>
-struct envelope<Multi, multi_polygon_tag>
- : detail::envelope::envelope_multi_polygon
-{};
-
-
-} // namespace dispatch
-#endif
-
-
-namespace resolve_variant {
-
-template <typename Geometry>
-struct envelope
-{
- template <typename Box>
- static inline void apply(Geometry const& geometry, Box& box)
- {
- concept::check<Geometry const>();
- concept::check<Box>();
-
- dispatch::envelope<Geometry>::apply(geometry, box);
- }
-};
-
-template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
-struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
-{
- template <typename Box>
- struct visitor: boost::static_visitor<void>
- {
- Box& m_box;
-
- visitor(Box& box): m_box(box) {}
-
- template <typename Geometry>
- void operator()(Geometry const& geometry) const
- {
- envelope<Geometry>::apply(geometry, m_box);
- }
- };
-
- template <typename Box>
- static inline void
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
- Box& box)
- {
- boost::apply_visitor(visitor<Box>(box), geometry);
- }
-};
-
-} // namespace resolve_variant
-
-
-/*!
-\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)
-{
- resolve_variant::envelope<Geometry>::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)
-{
- Box mbr;
- resolve_variant::envelope<Geometry>::apply(geometry, mbr);
- return mbr;
-}
-
-}} // namespace boost::geometry
+#include <boost/geometry/algorithms/detail/envelope/interface.hpp>
+#include <boost/geometry/algorithms/detail/envelope/implementation.hpp>
#endif // BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/equals.hpp b/3party/boost/boost/geometry/algorithms/equals.hpp
index c6b718da1b..a22080450c 100644
--- a/3party/boost/boost/geometry/algorithms/equals.hpp
+++ b/3party/boost/boost/geometry/algorithms/equals.hpp
@@ -1,14 +1,15 @@
// 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.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -26,6 +27,10 @@
#include <boost/range.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/geometry_id.hpp>
@@ -46,12 +51,11 @@
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/variant/apply_visitor.hpp>
namespace boost { namespace geometry
{
@@ -178,9 +182,9 @@ struct equals_by_collection
template<typename Geometry1, typename Geometry2>
struct equals_by_relate
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_equals_type,
+ detail::de9im::static_mask_equals_type,
Geometry1,
Geometry2
>
@@ -234,8 +238,6 @@ template <typename P1, typename P2, std::size_t DimensionCount, bool Reverse>
struct equals<P1, P2, point_tag, point_tag, DimensionCount, Reverse>
: geometry::detail::not_
<
- P1,
- P2,
detail::disjoint::point_point<P1, P2, 0, DimensionCount>
>
{};
diff --git a/3party/boost/boost/geometry/algorithms/expand.hpp b/3party/boost/boost/geometry/algorithms/expand.hpp
index 19e40aa2d0..6b4820d8a9 100644
--- a/3party/boost/boost/geometry/algorithms/expand.hpp
+++ b/3party/boost/boost/geometry/algorithms/expand.hpp
@@ -1,9 +1,14 @@
// 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.
-// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,333 +20,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
#define BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
-
-#include <cstddef>
-
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <boost/geometry/algorithms/not_implemented.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>
-
-#include <boost/variant/static_visitor.hpp>
-#include <boost/variant/apply_visitor.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace expand
-{
-
-
-template
-<
- typename StrategyLess, typename StrategyGreater,
- std::size_t Dimension, std::size_t DimensionCount
->
-struct point_loop
-{
- template <typename Box, typename Point>
- static inline void apply(Box& box, Point const& source)
- {
- 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;
-
- 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
- <
- StrategyLess, StrategyGreater,
- Dimension + 1, DimensionCount
- >::apply(box, source);
- }
-};
-
-
-template
-<
- typename StrategyLess, typename StrategyGreater,
- std::size_t DimensionCount
->
-struct point_loop
- <
- StrategyLess, StrategyGreater,
- DimensionCount, DimensionCount
- >
-{
- template <typename Box, typename Point>
- static inline void apply(Box&, Point const&) {}
-};
-
-
-template
-<
- typename StrategyLess, typename StrategyGreater,
- std::size_t Index,
- std::size_t Dimension, std::size_t DimensionCount
->
-struct indexed_loop
-{
- template <typename Box, typename Geometry>
- static inline void apply(Box& box, Geometry const& source)
- {
- 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;
-
- 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
- <
- StrategyLess, StrategyGreater,
- Index, Dimension + 1, DimensionCount
- >::apply(box, source);
- }
-};
-
-
-template
-<
- typename StrategyLess, typename StrategyGreater,
- std::size_t Index, std::size_t DimensionCount
->
-struct indexed_loop
- <
- StrategyLess, StrategyGreater,
- Index, DimensionCount, DimensionCount
- >
-{
- template <typename Box, typename Geometry>
- static inline void apply(Box&, Geometry const&) {}
-};
-
-
-
-// Changes a box such that the other box is also contained by the box
-template
-<
- typename StrategyLess, typename StrategyGreater
->
-struct expand_indexed
-{
- template <typename Box, typename Geometry>
- static inline void apply(Box& box, Geometry const& geometry)
- {
- indexed_loop
- <
- StrategyLess, StrategyGreater,
- 0, 0, dimension<Geometry>::type::value
- >::apply(box, geometry);
-
- indexed_loop
- <
- 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 GeometryOut, typename Geometry,
- typename StrategyLess = strategy::compare::default_strategy,
- typename StrategyGreater = strategy::compare::default_strategy,
- typename TagOut = typename tag<GeometryOut>::type,
- typename Tag = typename tag<Geometry>::type
->
-struct expand: not_implemented<TagOut, Tag>
-{};
-
-
-// Box + point -> new box containing also point
-template
-<
- typename BoxOut, typename Point,
- typename StrategyLess, typename StrategyGreater
->
-struct expand<BoxOut, Point, StrategyLess, StrategyGreater, box_tag, point_tag>
- : detail::expand::point_loop
- <
- 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<BoxOut, BoxIn, StrategyLess, StrategyGreater, box_tag, box_tag>
- : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
-{};
-
-template
-<
- typename Box, typename Segment,
- typename StrategyLess, typename StrategyGreater
->
-struct expand<Box, Segment, StrategyLess, StrategyGreater, box_tag, segment_tag>
- : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
-{};
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-namespace resolve_variant {
-
-template <typename Geometry>
-struct expand
-{
- template <typename Box>
- static inline void apply(Box& box, Geometry const& geometry)
- {
- concept::check<Box>();
- concept::check<Geometry const>();
- concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
-
- dispatch::expand<Box, Geometry>::apply(box, geometry);
- }
-};
-
-template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
-struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
-{
- template <typename Box>
- struct visitor: boost::static_visitor<void>
- {
- Box& m_box;
-
- visitor(Box& box) : m_box(box) {}
-
- template <typename Geometry>
- void operator()(Geometry const& geometry) const
- {
- return expand<Geometry>::apply(m_box, geometry);
- }
- };
-
- template <class Box>
- static inline void
- apply(Box& box,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
- {
- return boost::apply_visitor(visitor<Box>(box), geometry);
- }
-};
-
-} // namespace resolve_variant
-
-
-/***
-*!
-\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<Box, Geometry>::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)
-{
- resolve_variant::expand<Geometry>::apply(box, geometry);
-}
-
-}} // namespace boost::geometry
+#include <boost/geometry/algorithms/detail/expand/interface.hpp>
+#include <boost/geometry/algorithms/detail/expand/implementation.hpp>
#endif // BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
diff --git a/3party/boost/boost/geometry/algorithms/for_each.hpp b/3party/boost/boost/geometry/algorithms/for_each.hpp
index 036109d3c0..c5c099b1ad 100644
--- a/3party/boost/boost/geometry/algorithms/for_each.hpp
+++ b/3party/boost/boost/geometry/algorithms/for_each.hpp
@@ -1,10 +1,15 @@
// 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.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -24,6 +29,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/not_implemented.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_type.hpp>
@@ -35,6 +41,8 @@
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/util/add_const_if_c.hpp>
+#include <boost/geometry/util/range.hpp>
+
namespace boost { namespace geometry
{
@@ -86,7 +94,8 @@ struct fe_range_per_point
};
-struct fe_range_per_segment
+template <closure_selector Closure>
+struct fe_range_per_segment_with_closure
{
template <typename Range, typename Functor>
static inline void apply(Range& range, Functor& f)
@@ -96,8 +105,8 @@ struct fe_range_per_segment
is_const<Range>::value,
typename point_type<Range>::type
>::type point_type;
- typedef typename boost::range_iterator<Range>::type
- iterator_type;
+
+ typedef typename boost::range_iterator<Range>::type iterator_type;
iterator_type it = boost::begin(range);
iterator_type previous = it++;
@@ -111,6 +120,41 @@ struct fe_range_per_segment
};
+template <>
+struct fe_range_per_segment_with_closure<open>
+{
+ template <typename Range, typename Functor>
+ static inline void apply(Range& range, Functor& f)
+ {
+ fe_range_per_segment_with_closure<closed>::apply(range, f);
+
+ model::referring_segment
+ <
+ typename add_const_if_c
+ <
+ is_const<Range>::value,
+ typename point_type<Range>::type
+ >::type
+ > s(range::back(range), range::front(range));
+
+ f(s);
+ }
+};
+
+
+struct fe_range_per_segment
+{
+ template <typename Range, typename Functor>
+ static inline void apply(Range& range, Functor& f)
+ {
+ fe_range_per_segment_with_closure
+ <
+ closure<Range>::value
+ >::apply(range, f);
+ }
+};
+
+
struct fe_polygon_per_point
{
template <typename Polygon, typename Functor>
diff --git a/3party/boost/boost/geometry/algorithms/intersection.hpp b/3party/boost/boost/geometry/algorithms/intersection.hpp
index b066e8150c..0169f12db1 100644
--- a/3party/boost/boost/geometry/algorithms/intersection.hpp
+++ b/3party/boost/boost/geometry/algorithms/intersection.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -10,310 +15,8 @@
#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/detail/overlay/intersection_box_box.hpp>
-#include <boost/geometry/algorithms/intersects.hpp>
-#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-// By default, all is forwarded to the intersection_insert-dispatcher
-template
-<
- typename Geometry1, typename Geometry2,
- typename Tag1 = typename geometry::tag<Geometry1>::type,
- typename Tag2 = typename geometry::tag<Geometry2>::type,
- bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
->
-struct intersection
-{
- template <typename RobustPolicy, typename GeometryOut, typename Strategy>
- static inline bool apply(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- RobustPolicy const& robust_policy,
- GeometryOut& geometry_out,
- Strategy const& strategy)
- {
- typedef typename boost::range_value<GeometryOut>::type OneOut;
-
- intersection_insert
- <
- Geometry1, Geometry2, OneOut,
- overlay_intersection
- >::apply(geometry1, geometry2, robust_policy, std::back_inserter(geometry_out), strategy);
-
- return true;
- }
-
-};
-
-
-// If reversal is needed, perform it
-template
-<
- typename Geometry1, typename Geometry2,
- typename Tag1, typename Tag2
->
-struct intersection
-<
- Geometry1, Geometry2,
- Tag1, Tag2,
- true
->
- : intersection<Geometry2, Geometry1, Tag2, Tag1, false>
-{
- template <typename RobustPolicy, typename GeometryOut, typename Strategy>
- static inline bool apply(
- Geometry1 const& g1,
- Geometry2 const& g2,
- RobustPolicy const& robust_policy,
- GeometryOut& out,
- Strategy const& strategy)
- {
- return intersection<
- Geometry2, Geometry1,
- Tag2, Tag1,
- false
- >::apply(g2, g1, robust_policy, out, strategy);
- }
-};
-
-
-template
-<
- typename Box1, typename Box2, bool Reverse
->
-struct intersection
- <
- Box1, Box2,
- box_tag, box_tag,
- Reverse
- > : public detail::intersection::intersection_box_box
- <
- 0, geometry::dimension<Box1>::value
- >
-{};
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-namespace resolve_variant
-{
-
-template <typename Geometry1, typename Geometry2>
-struct intersection
-{
- template <typename GeometryOut>
- static inline bool
- apply(
- const Geometry1& geometry1,
- const Geometry2& geometry2,
- GeometryOut& geometry_out)
- {
- concept::check<Geometry1 const>();
- concept::check<Geometry2 const>();
-
- typedef typename geometry::rescale_overlay_policy_type
- <
- Geometry1,
- Geometry2
- >::type rescale_policy_type;
-
- rescale_policy_type robust_policy
- = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
-
- typedef strategy_intersection
- <
- typename cs_tag<Geometry1>::type,
- Geometry1,
- Geometry2,
- typename geometry::point_type<Geometry1>::type,
- rescale_policy_type
- > strategy;
-
- return dispatch::intersection
- <
- Geometry1,
- Geometry2
- >::apply(geometry1, geometry2, robust_policy, geometry_out, strategy());
- }
-};
-
-
-template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
-struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
-{
- template <typename GeometryOut>
- struct visitor: static_visitor<bool>
- {
- Geometry2 const& m_geometry2;
- GeometryOut& m_geometry_out;
-
- visitor(Geometry2 const& geometry2,
- GeometryOut& geometry_out)
- : m_geometry2(geometry2),
- m_geometry_out(geometry_out)
- {}
-
- template <typename Geometry1>
- result_type operator()(Geometry1 const& geometry1) const
- {
- return intersection
- <
- Geometry1,
- Geometry2
- >::template apply
- <
- GeometryOut
- >
- (geometry1, m_geometry2, m_geometry_out);
- }
- };
-
- template <typename GeometryOut>
- static inline bool
- apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
- Geometry2 const& geometry2,
- GeometryOut& geometry_out)
- {
- return apply_visitor(visitor<GeometryOut>(geometry2, geometry_out), geometry1);
- }
-};
-
-
-template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
-struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
-{
- template <typename GeometryOut>
- struct visitor: static_visitor<bool>
- {
- Geometry1 const& m_geometry1;
- GeometryOut& m_geometry_out;
-
- visitor(Geometry1 const& geometry1,
- GeometryOut& geometry_out)
- : m_geometry1(geometry1),
- m_geometry_out(geometry_out)
- {}
-
- template <typename Geometry2>
- result_type operator()(Geometry2 const& geometry2) const
- {
- return intersection
- <
- Geometry1,
- Geometry2
- >::template apply
- <
- GeometryOut
- >
- (m_geometry1, geometry2, m_geometry_out);
- }
- };
-
- template <typename GeometryOut>
- static inline bool
- apply(
- Geometry1 const& geometry1,
- const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
- GeometryOut& geometry_out)
- {
- return apply_visitor(visitor<GeometryOut>(geometry1, geometry_out), geometry2);
- }
-};
-
-
-template <BOOST_VARIANT_ENUM_PARAMS(typename A), BOOST_VARIANT_ENUM_PARAMS(typename B)>
-struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(A)>, variant<BOOST_VARIANT_ENUM_PARAMS(B)> >
-{
- template <typename GeometryOut>
- struct visitor: static_visitor<bool>
- {
- GeometryOut& m_geometry_out;
-
- visitor(GeometryOut& geometry_out)
- : m_geometry_out(geometry_out)
- {}
-
- template <typename Geometry1, typename Geometry2>
- result_type operator()(
- Geometry1 const& geometry1,
- Geometry2 const& geometry2) const
- {
- return intersection
- <
- Geometry1,
- Geometry2
- >::template apply
- <
- GeometryOut
- >
- (geometry1, geometry2, m_geometry_out);
- }
- };
-
- template <typename GeometryOut>
- static inline bool
- apply(
- const variant<BOOST_VARIANT_ENUM_PARAMS(A)>& geometry1,
- const variant<BOOST_VARIANT_ENUM_PARAMS(B)>& geometry2,
- GeometryOut& geometry_out)
- {
- return apply_visitor(visitor<GeometryOut>(geometry_out), geometry1, geometry2);
- }
-};
-
-} // namespace resolve_variant
-
-
-/*!
-\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)
-{
- return resolve_variant::intersection
- <
- Geometry1,
- Geometry2
- >::template apply
- <
- GeometryOut
- >
- (geometry1, geometry2, geometry_out);
-}
-
-
-}} // namespace boost::geometry
+#include <boost/geometry/algorithms/detail/intersection/interface.hpp>
+#include <boost/geometry/algorithms/detail/intersection/implementation.hpp>
#endif // BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP
diff --git a/3party/boost/boost/geometry/algorithms/intersects.hpp b/3party/boost/boost/geometry/algorithms/intersects.hpp
index 12cf78173b..1bb85aa3bb 100644
--- a/3party/boost/boost/geometry/algorithms/intersects.hpp
+++ b/3party/boost/boost/geometry/algorithms/intersects.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2013-2014.
+// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -21,8 +26,8 @@
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
-#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
namespace boost { namespace geometry
@@ -47,8 +52,7 @@ inline bool intersects(Geometry const& geometry)
concept::check<Geometry const>();
typedef typename geometry::point_type<Geometry>::type point_type;
- typedef typename rescale_policy_type<point_type>::type
- rescale_policy_type;
+ typedef detail::no_rescale_policy rescale_policy_type;
typedef detail::overlay::turn_info
<
@@ -63,8 +67,7 @@ inline bool intersects(Geometry const& geometry)
detail::overlay::assign_null_policy
> turn_policy;
- rescale_policy_type robust_policy
- = geometry::get_rescale_policy<rescale_policy_type>(geometry);
+ rescale_policy_type robust_policy;
detail::disjoint::disjoint_interrupt_policy policy;
detail::self_get_turn_points::get_turns
diff --git a/3party/boost/boost/geometry/algorithms/is_convex.hpp b/3party/boost/boost/geometry/algorithms/is_convex.hpp
new file mode 100644
index 0000000000..8feb48db6a
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/is_convex.hpp
@@ -0,0 +1,160 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 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_IS_CONVEX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_IS_CONVEX_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/iterators/ever_circling_iterator.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
+#include <boost/geometry/views/detail/normalized_view.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace is_convex
+{
+
+struct ring_is_convex
+{
+ template <typename Ring>
+ static inline bool apply(Ring const& ring)
+ {
+ typedef typename geometry::point_type<Ring>::type point_type;
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<point_type>::type
+ >::type side_strategy_type;
+
+ std::size_t n = boost::size(ring);
+ if (boost::size(ring) < core_detail::closure::minimum_ring_size
+ <
+ geometry::closure<Ring>::value
+ >::value)
+ {
+ // (Too) small rings are considered as non-concave, is convex
+ return true;
+ }
+
+ // Walk in clockwise direction, consider ring as closed
+ // (though closure is not important in this algorithm - any dupped
+ // point is skipped)
+ typedef detail::normalized_view<Ring const> view_type;
+ view_type view(ring);
+
+ typedef geometry::ever_circling_range_iterator<view_type const> it_type;
+ it_type previous(view);
+ it_type current(view);
+ current++;
+
+ std::size_t index = 1;
+ while (equals::equals_point_point(*current, *previous) && index < n)
+ {
+ current++;
+ index++;
+ }
+
+ if (index == n)
+ {
+ // All points are apparently equal
+ return true;
+ }
+
+ it_type next = current;
+ next++;
+ while (equals::equals_point_point(*current, *next))
+ {
+ next++;
+ }
+
+ // We have now three different points on the ring
+ // Walk through all points, use a counter because of the ever-circling
+ // iterator
+ for (std::size_t i = 0; i < n; i++)
+ {
+ int const side = side_strategy_type::apply(*previous, *current, *next);
+ if (side == 1)
+ {
+ // Next is on the left side of clockwise ring:
+ // the piece is not convex
+ return false;
+ }
+
+ previous = current;
+ current = next;
+
+ // Advance next to next different point
+ // (because there are non-equal points, this loop is not infinite)
+ next++;
+ while (equals::equals_point_point(*current, *next))
+ {
+ next++;
+ }
+ }
+ return true;
+ }
+};
+
+
+}} // namespace detail::is_convex
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry,
+ typename Tag = typename tag<Geometry>::type
+>
+struct is_convex : not_implemented<Tag>
+{};
+
+template <typename Box>
+struct is_convex<Box, box_tag>
+{
+ static inline bool apply(Box const& )
+ {
+ // Any box is convex (TODO: consider spherical boxes)
+ return true;
+ }
+};
+
+template <typename Box>
+struct is_convex<Box, ring_tag> : detail::is_convex::ring_is_convex
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+// TODO: variants
+
+// TODO: documentation / qbk
+template<typename Geometry>
+inline bool is_convex(Geometry const& geometry)
+{
+ return dispatch::is_convex<Geometry>::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_IS_CONVEX_HPP
diff --git a/3party/boost/boost/geometry/algorithms/is_empty.hpp b/3party/boost/boost/geometry/algorithms/is_empty.hpp
new file mode 100644
index 0000000000..02c295eaba
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/is_empty.hpp
@@ -0,0 +1,207 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace is_empty
+{
+
+struct always_not_empty
+{
+ template <typename Geometry>
+ static inline bool apply(Geometry const&)
+ {
+ return false;
+ }
+};
+
+struct range_is_empty
+{
+ template <typename Range>
+ static inline bool apply(Range const& range)
+ {
+ return boost::empty(range);
+ }
+};
+
+class polygon_is_empty
+{
+ template <typename InteriorRings>
+ static inline bool check_interior_rings(InteriorRings const& interior_rings)
+ {
+ return check_iterator_range
+ <
+ range_is_empty, true // allow empty range
+ >::apply(boost::begin(interior_rings), boost::end(interior_rings));
+ }
+
+public:
+ template <typename Polygon>
+ static inline bool apply(Polygon const& polygon)
+ {
+ return boost::empty(exterior_ring(polygon))
+ && check_interior_rings(interior_rings(polygon));
+ }
+};
+
+template <typename Policy = range_is_empty>
+struct multi_is_empty
+{
+ template <typename MultiGeometry>
+ static inline bool apply(MultiGeometry const& multigeometry)
+ {
+ return check_iterator_range
+ <
+ Policy, true // allow empty range
+ >::apply(boost::begin(multigeometry), boost::end(multigeometry));
+ }
+
+};
+
+}} // namespace detail::is_empty
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct is_empty : not_implemented<Tag>
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, point_tag>
+ : detail::is_empty::always_not_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, box_tag>
+ : detail::is_empty::always_not_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, segment_tag>
+ : detail::is_empty::always_not_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, linestring_tag>
+ : detail::is_empty::range_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, ring_tag>
+ : detail::is_empty::range_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, polygon_tag>
+ : detail::is_empty::polygon_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, multi_point_tag>
+ : detail::is_empty::range_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, multi_linestring_tag>
+ : detail::is_empty::multi_is_empty<>
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, multi_polygon_tag>
+ : detail::is_empty::multi_is_empty<detail::is_empty::polygon_is_empty>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct is_empty
+{
+ static inline bool apply(Geometry const& geometry)
+ {
+ concept::check<Geometry const>();
+
+ return dispatch::is_empty<Geometry>::apply(geometry);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct is_empty<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ struct visitor : boost::static_visitor<bool>
+ {
+ template <typename Geometry>
+ inline bool operator()(Geometry const& geometry) const
+ {
+ return is_empty<Geometry>::apply(geometry);
+ }
+ };
+
+ static bool
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ {
+ return boost::apply_visitor(visitor(), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/*!
+\brief \brief_check{is the empty set}
+\ingroup is_empty
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_check{is the empty set}
+
+\qbk{[include reference/algorithms/is_empty.qbk]}
+*/
+template <typename Geometry>
+inline bool is_empty(Geometry const& geometry)
+{
+ return resolve_variant::is_empty<Geometry>::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
diff --git a/3party/boost/boost/geometry/algorithms/length.hpp b/3party/boost/boost/geometry/algorithms/length.hpp
index 6cbec5303e..fad17ade46 100644
--- a/3party/boost/boost/geometry/algorithms/length.hpp
+++ b/3party/boost/boost/geometry/algorithms/length.hpp
@@ -4,10 +4,11 @@
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -22,6 +23,7 @@
#include <iterator>
#include <boost/concept_check.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/mpl/fold.hpp>
@@ -69,6 +71,7 @@ struct segment_length
static inline typename default_length_result<Segment>::type apply(
Segment const& segment, Strategy const& strategy)
{
+ boost::ignore_unused(strategy);
typedef typename point_type<Segment>::type point_type;
point_type p1, p2;
geometry::detail::assign_point_from_index<0>(segment, p1);
@@ -92,7 +95,7 @@ struct range_length
static inline return_type apply(
Range const& range, Strategy const& strategy)
{
- boost::ignore_unused_variable_warning(strategy);
+ boost::ignore_unused(strategy);
typedef typename closeable_view<Range const, Closure>::type view_type;
typedef typename boost::range_iterator
<
diff --git a/3party/boost/boost/geometry/algorithms/not_implemented.hpp b/3party/boost/boost/geometry/algorithms/not_implemented.hpp
index cd40a2772f..9c416074ed 100644
--- a/3party/boost/boost/geometry/algorithms/not_implemented.hpp
+++ b/3party/boost/boost/geometry/algorithms/not_implemented.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -17,6 +22,7 @@
#include <boost/mpl/assert.hpp>
+#include <boost/mpl/identity.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -87,7 +93,7 @@ template <> struct tag_to_term<multi_point_tag> { typedef info::MULT
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 <int D> struct tag_to_term<boost::mpl::int_<D> > { typedef info::DIMENSION<D> type; };
}
@@ -103,9 +109,18 @@ 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
+ typename boost::mpl::identity
+ <
+ typename nyi::tag_to_term<Term1>::type
+ >::type,
+ typename boost::mpl::identity
+ <
+ typename nyi::tag_to_term<Term2>::type
+ >::type,
+ typename boost::mpl::identity
+ <
+ typename nyi::tag_to_term<Term3>::type
+ >::type
>
{};
diff --git a/3party/boost/boost/geometry/algorithms/num_geometries.hpp b/3party/boost/boost/geometry/algorithms/num_geometries.hpp
index c32494607e..8144c22ab0 100644
--- a/3party/boost/boost/geometry/algorithms/num_geometries.hpp
+++ b/3party/boost/boost/geometry/algorithms/num_geometries.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -19,6 +24,10 @@
#include <boost/range.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/tag.hpp>
@@ -27,6 +36,8 @@
#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/algorithms/detail/counting.hpp>
+
namespace boost { namespace geometry
{
@@ -53,12 +64,8 @@ struct num_geometries: not_implemented<Tag>
template <typename Geometry>
struct num_geometries<Geometry, single_tag>
-{
- static inline std::size_t apply(Geometry const&)
- {
- return 1;
- }
-};
+ : detail::counting::other_count<1>
+{};
template <typename MultiGeometry>
@@ -72,7 +79,43 @@ struct num_geometries<MultiGeometry, multi_tag>
} // namespace dispatch
-#endif
+#endif // DOXYGEN_NO_DISPATCH
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct num_geometries
+{
+ static inline std::size_t apply(Geometry const& geometry)
+ {
+ concept::check<Geometry const>();
+
+ return dispatch::num_geometries<Geometry>::apply(geometry);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct num_geometries<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ struct visitor: boost::static_visitor<std::size_t>
+ {
+ template <typename Geometry>
+ inline std::size_t operator()(Geometry const& geometry) const
+ {
+ return num_geometries<Geometry>::apply(geometry);
+ }
+ };
+
+ static inline std::size_t
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ {
+ return boost::apply_visitor(visitor(), geometry);
+ }
+};
+
+} // namespace resolve_variant
/*!
@@ -88,9 +131,7 @@ struct num_geometries<MultiGeometry, multi_tag>
template <typename Geometry>
inline std::size_t num_geometries(Geometry const& geometry)
{
- concept::check<Geometry const>();
-
- return dispatch::num_geometries<Geometry>::apply(geometry);
+ return resolve_variant::num_geometries<Geometry>::apply(geometry);
}
diff --git a/3party/boost/boost/geometry/algorithms/num_interior_rings.hpp b/3party/boost/boost/geometry/algorithms/num_interior_rings.hpp
index e815f5981d..04b4eb2a7c 100644
--- a/3party/boost/boost/geometry/algorithms/num_interior_rings.hpp
+++ b/3party/boost/boost/geometry/algorithms/num_interior_rings.hpp
@@ -1,8 +1,14 @@
// 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.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -18,11 +24,19 @@
#include <boost/range.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/algorithms/detail/counting.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
namespace boost { namespace geometry
{
@@ -34,12 +48,8 @@ namespace dispatch
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct num_interior_rings
-{
- static inline std::size_t apply(Geometry const& )
- {
- return 0;
- }
-};
+ : detail::counting::other_count<0>
+{};
@@ -54,8 +64,56 @@ struct num_interior_rings<Polygon, polygon_tag>
};
+template <typename MultiPolygon>
+struct num_interior_rings<MultiPolygon, multi_polygon_tag>
+ : detail::counting::multi_count
+ <
+ num_interior_rings
+ <
+ typename boost::range_value<MultiPolygon const>::type
+ >
+ >
+{};
+
+
} // namespace dispatch
-#endif
+#endif // DOXYGEN_NO_DISPATCH
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct num_interior_rings
+{
+ static inline std::size_t apply(Geometry const& geometry)
+ {
+ concept::check<Geometry const>();
+
+ return dispatch::num_interior_rings<Geometry>::apply(geometry);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct num_interior_rings<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ struct visitor: boost::static_visitor<std::size_t>
+ {
+ template <typename Geometry>
+ inline std::size_t operator()(Geometry const& geometry) const
+ {
+ return num_interior_rings<Geometry>::apply(geometry);
+ }
+ };
+
+ static inline std::size_t
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ {
+ return boost::apply_visitor(visitor(), geometry);
+ }
+};
+
+} // namespace resolve_variant
/*!
@@ -74,7 +132,7 @@ struct num_interior_rings<Polygon, polygon_tag>
template <typename Geometry>
inline std::size_t num_interior_rings(Geometry const& geometry)
{
- return dispatch::num_interior_rings<Geometry>::apply(geometry);
+ return resolve_variant::num_interior_rings<Geometry>::apply(geometry);
}
diff --git a/3party/boost/boost/geometry/algorithms/num_points.hpp b/3party/boost/boost/geometry/algorithms/num_points.hpp
index d8dc91aceb..214fe9c8b0 100644
--- a/3party/boost/boost/geometry/algorithms/num_points.hpp
+++ b/3party/boost/boost/geometry/algorithms/num_points.hpp
@@ -1,10 +1,15 @@
// 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.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -17,19 +22,24 @@
#include <cstddef>
+#include <boost/mpl/size_t.hpp>
+
#include <boost/range.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.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/coordinate_dimension.hpp>
#include <boost/geometry/core/tag_cast.hpp>
-#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
-#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/core/tags.hpp>
+
#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/algorithms/detail/counting.hpp>
+
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/variant/apply_visitor.hpp>
-#include <boost/variant/variant_fwd.hpp>
namespace boost { namespace geometry
@@ -47,55 +57,24 @@ namespace detail { namespace num_points
{
+template <bool AddForOpen>
struct range_count
{
template <typename Range>
- static inline std::size_t apply(Range const& range, bool add_for_open)
+ static inline std::size_t apply(Range const& range)
{
std::size_t n = boost::size(range);
- if (add_for_open && n > 0)
+ if (AddForOpen
+ && n > 0
+ && geometry::closure<Range>::value == open
+ )
{
- if (geometry::closure<Range>::value == open)
- {
- if (geometry::disjoint(*boost::begin(range), *(boost::begin(range) + n - 1)))
- {
- return n + 1;
- }
- }
+ return n + 1;
}
return n;
}
};
-template <std::size_t D>
-struct other_count
-{
- template <typename Geometry>
- static inline std::size_t apply(Geometry const&, bool)
- {
- return D;
- }
-};
-
-struct polygon_count: private range_count
-{
- template <typename Polygon>
- static inline std::size_t apply(Polygon const& poly, bool add_for_open)
- {
- std::size_t n = range_count::apply(exterior_ring(poly), add_for_open);
-
- typename interior_return_type<Polygon const>::type
- rings = interior_rings(poly);
- for (typename detail::interior_iterator<Polygon const>::type
- it = boost::begin(rings); it != boost::end(rings); ++it)
- {
- n += range_count::apply(*it, add_for_open);
- }
-
- return n;
- }
-};
-
}} // namespace detail::num_points
#endif // DOXYGEN_NO_DETAIL
@@ -107,46 +86,62 @@ namespace dispatch
template
<
typename Geometry,
- typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
+ bool AddForOpen,
+ typename Tag = typename tag_cast
+ <
+ typename tag<Geometry>::type, multi_tag
+ >::type
>
struct num_points: not_implemented<Tag>
{};
-template <typename Geometry>
-struct num_points<Geometry, point_tag>
- : detail::num_points::other_count<1>
+template <typename Geometry, bool AddForOpen>
+struct num_points<Geometry, AddForOpen, point_tag>
+ : detail::counting::other_count<1>
{};
-template <typename Geometry>
-struct num_points<Geometry, box_tag>
- : detail::num_points::other_count<4>
+template <typename Geometry, bool AddForOpen>
+struct num_points<Geometry, AddForOpen, box_tag>
+ : detail::counting::other_count<(1 << geometry::dimension<Geometry>::value)>
{};
-template <typename Geometry>
-struct num_points<Geometry, segment_tag>
- : detail::num_points::other_count<2>
+template <typename Geometry, bool AddForOpen>
+struct num_points<Geometry, AddForOpen, segment_tag>
+ : detail::counting::other_count<2>
{};
-template <typename Geometry>
-struct num_points<Geometry, linestring_tag>
- : detail::num_points::range_count
+template <typename Geometry, bool AddForOpen>
+struct num_points<Geometry, AddForOpen, linestring_tag>
+ : detail::num_points::range_count<AddForOpen>
{};
-template <typename Geometry>
-struct num_points<Geometry, ring_tag>
- : detail::num_points::range_count
+template <typename Geometry, bool AddForOpen>
+struct num_points<Geometry, AddForOpen, ring_tag>
+ : detail::num_points::range_count<AddForOpen>
{};
-template <typename Geometry>
-struct num_points<Geometry, polygon_tag>
- : detail::num_points::polygon_count
+template <typename Geometry, bool AddForOpen>
+struct num_points<Geometry, AddForOpen, polygon_tag>
+ : detail::counting::polygon_count
+ <
+ detail::num_points::range_count<AddForOpen>
+ >
+{};
+
+template <typename Geometry, bool AddForOpen>
+struct num_points<Geometry, AddForOpen, multi_tag>
+ : detail::counting::multi_count
+ <
+ num_points<typename boost::range_value<Geometry>::type, AddForOpen>
+ >
{};
} // namespace dispatch
#endif
-namespace resolve_variant {
+namespace resolve_variant
+{
template <typename Geometry>
struct num_points
@@ -154,7 +149,11 @@ struct num_points
static inline std::size_t apply(Geometry const& geometry,
bool add_for_open)
{
- return dispatch::num_points<Geometry>::apply(geometry, add_for_open);
+ concept::check<Geometry const>();
+
+ return add_for_open
+ ? dispatch::num_points<Geometry, true>::apply(geometry)
+ : dispatch::num_points<Geometry, false>::apply(geometry);
}
};
@@ -168,7 +167,7 @@ struct num_points<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
visitor(bool add_for_open): m_add_for_open(add_for_open) {}
template <typename Geometry>
- typename std::size_t operator()(Geometry const& geometry) const
+ inline std::size_t operator()(Geometry const& geometry) const
{
return num_points<Geometry>::apply(geometry, m_add_for_open);
}
@@ -199,8 +198,6 @@ struct num_points<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
template <typename Geometry>
inline std::size_t num_points(Geometry const& geometry, bool add_for_open = false)
{
- concept::check<Geometry const>();
-
return resolve_variant::num_points<Geometry>::apply(geometry, add_for_open);
}
diff --git a/3party/boost/boost/geometry/algorithms/num_segments.hpp b/3party/boost/boost/geometry/algorithms/num_segments.hpp
new file mode 100644
index 0000000000..08af226caf
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/num_segments.hpp
@@ -0,0 +1,204 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/size_t.hpp>
+#include <boost/mpl/times.hpp>
+
+#include <boost/range.hpp>
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/algorithms/detail/counting.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace num_segments
+{
+
+
+struct range_count
+{
+ template <typename Range>
+ static inline std::size_t apply(Range const& range)
+ {
+ std::size_t n = boost::size(range);
+ if ( n <= 1 )
+ {
+ return 0;
+ }
+
+ return
+ geometry::closure<Range>::value == open
+ ?
+ n
+ :
+ static_cast<std::size_t>(n - 1);
+ }
+};
+
+}} // namespace detail::num_segments
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct num_segments
+ : not_implemented<Tag>
+{};
+
+template <typename Geometry>
+struct num_segments<Geometry, point_tag>
+ : detail::counting::other_count<0>
+{};
+
+// the number of segments (1-dimensional faces) of the hypercube is
+// given by the formula: d * 2^(d-1), where d is the dimension of the
+// hypercube; see also:
+// http://en.wikipedia.org/wiki/Hypercube
+template <typename Geometry>
+struct num_segments<Geometry, box_tag>
+ : detail::counting::other_count
+ <
+ geometry::dimension<Geometry>::value
+ * (1 << (geometry::dimension<Geometry>::value - 1))
+ >
+{};
+
+template <typename Geometry>
+struct num_segments<Geometry, segment_tag>
+ : detail::counting::other_count<1>
+{};
+
+template <typename Geometry>
+struct num_segments<Geometry, linestring_tag>
+ : detail::num_segments::range_count
+{};
+
+template <typename Geometry>
+struct num_segments<Geometry, ring_tag>
+ : detail::num_segments::range_count
+{};
+
+template <typename Geometry>
+struct num_segments<Geometry, polygon_tag>
+ : detail::counting::polygon_count<detail::num_segments::range_count>
+{};
+
+template <typename Geometry>
+struct num_segments<Geometry, multi_point_tag>
+ : detail::counting::other_count<0>
+{};
+
+template <typename Geometry>
+struct num_segments<Geometry, multi_linestring_tag>
+ : detail::counting::multi_count
+ <
+ num_segments< typename boost::range_value<Geometry>::type>
+ >
+{};
+
+template <typename Geometry>
+struct num_segments<Geometry, multi_polygon_tag>
+ : detail::counting::multi_count
+ <
+ num_segments< typename boost::range_value<Geometry>::type>
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+namespace resolve_variant
+{
+
+
+template <typename Geometry>
+struct num_segments
+{
+ static inline std::size_t apply(Geometry const& geometry)
+ {
+ concept::check<Geometry const>();
+
+ return dispatch::num_segments<Geometry>::apply(geometry);
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct num_segments<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ struct visitor: boost::static_visitor<std::size_t>
+ {
+ template <typename Geometry>
+ inline std::size_t operator()(Geometry const& geometry) const
+ {
+ return num_segments<Geometry>::apply(geometry);
+ }
+ };
+
+ static inline std::size_t
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ {
+ return boost::apply_visitor(visitor(), geometry);
+ }
+};
+
+
+} // namespace resolve_variant
+
+
+
+/*!
+\brief \brief_calc{number of segments}
+\ingroup num_segments
+\details \details_calc{num_segments, number of segments}.
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_calc{number of segments}
+
+\qbk{[include reference/algorithms/num_segments.qbk]}
+*/
+template <typename Geometry>
+inline std::size_t num_segments(Geometry const& geometry)
+{
+ return resolve_variant::num_segments<Geometry>::apply(geometry);
+}
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP
diff --git a/3party/boost/boost/geometry/algorithms/overlaps.hpp b/3party/boost/boost/geometry/algorithms/overlaps.hpp
index f724a544fd..96310d6cb5 100644
--- a/3party/boost/boost/geometry/algorithms/overlaps.hpp
+++ b/3party/boost/boost/geometry/algorithms/overlaps.hpp
@@ -28,7 +28,8 @@
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
namespace boost { namespace geometry
{
@@ -149,9 +150,9 @@ template
typename Tag2 = typename tag<Geometry2>::type
>
struct overlaps
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_overlaps_type,
+ detail::de9im::static_mask_overlaps_type,
Geometry1,
Geometry2
>
diff --git a/3party/boost/boost/geometry/algorithms/perimeter.hpp b/3party/boost/boost/geometry/algorithms/perimeter.hpp
index 0ec153c1f4..1b5ccacf9c 100644
--- a/3party/boost/boost/geometry/algorithms/perimeter.hpp
+++ b/3party/boost/boost/geometry/algorithms/perimeter.hpp
@@ -20,8 +20,9 @@
#define BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
#include <boost/range/metafunctions.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/length.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/point_on_surface.hpp b/3party/boost/boost/geometry/algorithms/point_on_surface.hpp
index a6f7ed71d7..3fa83bfe6f 100644
--- a/3party/boost/boost/geometry/algorithms/point_on_surface.hpp
+++ b/3party/boost/boost/geometry/algorithms/point_on_surface.hpp
@@ -5,6 +5,11 @@
// Copyright (c) 2009-2013 Mateusz Loskot, London, UK.
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -142,63 +147,30 @@ struct min_of_intruder
}
};
-template <typename Point, typename Segments>
-inline void calculate_centroid(Point& point, Segments const& segments)
-{
- if (segments.size() == 3)
- {
- // In almost all cases, the segments do have 3 values. In that case we use another
- // centroid calculation, which should be slightly faster
- // and is more precise (case #geos_1_test_overlay => normal centroid is outside! TODO)
-
- typedef typename geometry::coordinate_type<Point>::type coordinate_type;
- coordinate_type const three = 3.0;
- coordinate_type const sx = geometry::get<0>(segments[0]) + geometry::get<0>(segments[1]) + geometry::get<0>(segments[2]);
- coordinate_type const sy = geometry::get<1>(segments[0]) + geometry::get<1>(segments[1]) + geometry::get<1>(segments[2]);
- geometry::set<0>(point, sx / three);
- geometry::set<1>(point, sy / three);
- return;
- }
-
- // For 4 or more segments, we use normal centroid calculation
-
- // Specify centroid, it should have "areal_tag" to have correct calculation
- typedef typename strategy::centroid::services::default_strategy
- <
- typename cs_tag<Point>::type,
- areal_tag,
- dimension<Point>::type::value,
- Point,
- Point
- >::type strategy_type;
- strategy_type strategy;
-
-
- // Ignore warning (because using static method sometimes) on strategy
- boost::ignore_unused_variable_warning(strategy);
-
-
- typename strategy_type::state_type state;
+template <typename Point, typename P>
+inline void calculate_average(Point& point, std::vector<P> const& points)
+{
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+ typedef typename std::vector<P>::const_iterator iterator_type;
+ typedef typename std::vector<P>::size_type size_type;
- typedef typename boost::range_iterator<Segments const>::type iterator_type;
+ coordinate_type x = 0;
+ coordinate_type y = 0;
- iterator_type begin = boost::begin(segments);
- iterator_type end = boost::end(segments);
- iterator_type it = begin;
- iterator_type previous = it++;
- for (; it != end; ++previous, ++it)
+ iterator_type end = points.end();
+ for ( iterator_type it = points.begin() ; it != end ; ++it)
{
- strategy.apply(*previous, *it, state);
+ x += geometry::get<0>(*it);
+ y += geometry::get<1>(*it);
}
- // Close it explicitly:
- strategy.apply(*previous, *begin, state);
- strategy.result(state, point);
+ size_type const count = points.size();
+ geometry::set<0>(point, x / count);
+ geometry::set<1>(point, y / count);
}
-
template <int Dimension, typename Extremes, typename Intruders, typename CoordinateType>
inline void replace_extremes_for_self_tangencies(Extremes& extremes, Intruders& intruders, CoordinateType const& max_intruder)
{
@@ -304,8 +276,8 @@ inline bool calculate_point_on_surface(Geometry const& geometry, Point& point)
}
}
- // Now calculate the centroid of the (possibly adapted) extremes
- calculate_centroid(point, extremes);
+ // Now calculate the average/centroid of the (possibly adapted) extremes
+ calculate_average(point, extremes);
return true;
}
diff --git a/3party/boost/boost/geometry/algorithms/relate.hpp b/3party/boost/boost/geometry/algorithms/relate.hpp
new file mode 100644
index 0000000000..34733ec596
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/relate.hpp
@@ -0,0 +1,17 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_RELATE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_RELATE_HPP
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+#include <boost/geometry/algorithms/detail/relate/implementation.hpp>
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_RELATE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/relation.hpp b/3party/boost/boost/geometry/algorithms/relation.hpp
new file mode 100644
index 0000000000..c3cf2f99f8
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/relation.hpp
@@ -0,0 +1,17 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_RELATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_RELATION_HPP
+
+#include <boost/geometry/algorithms/detail/relation/interface.hpp>
+#include <boost/geometry/algorithms/detail/relation/implementation.hpp>
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_RELATION_HPP
diff --git a/3party/boost/boost/geometry/algorithms/remove_spikes.hpp b/3party/boost/boost/geometry/algorithms/remove_spikes.hpp
index e62ea9fe3d..a96a2c29d0 100644
--- a/3party/boost/boost/geometry/algorithms/remove_spikes.hpp
+++ b/3party/boost/boost/geometry/algorithms/remove_spikes.hpp
@@ -16,8 +16,9 @@
#include <boost/range.hpp>
#include <boost/type_traits/remove_reference.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/closure.hpp>
@@ -26,11 +27,15 @@
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/point_order.hpp>
#include <boost/geometry/core/tags.hpp>
+
#include <boost/geometry/geometries/concepts/check.hpp>
+
#include <boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/util/condition.hpp>
+
/*
Remove spikes from a ring/polygon.
@@ -94,7 +99,7 @@ struct range_remove_spikes
}
// For a closed-polygon, remove closing point, this makes checking first point(s) easier and consistent
- if (geometry::closure<Range>::value == geometry::closed)
+ if ( BOOST_GEOMETRY_CONDITION(geometry::closure<Range>::value == geometry::closed) )
{
cleaned.pop_back();
}
@@ -127,7 +132,7 @@ struct range_remove_spikes
}
// Close if necessary
- if (geometry::closure<Range>::value == geometry::closed)
+ if ( BOOST_GEOMETRY_CONDITION(geometry::closure<Range>::value == geometry::closed) )
{
cleaned.push_back(cleaned.front());
}
diff --git a/3party/boost/boost/geometry/algorithms/reverse.hpp b/3party/boost/boost/geometry/algorithms/reverse.hpp
index 17b23ffdfb..578771bfe3 100644
--- a/3party/boost/boost/geometry/algorithms/reverse.hpp
+++ b/3party/boost/boost/geometry/algorithms/reverse.hpp
@@ -19,8 +19,9 @@
#include <boost/range.hpp>
#include <boost/type_traits/remove_reference.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/simplify.hpp b/3party/boost/boost/geometry/algorithms/simplify.hpp
index 101b1324e1..0047546718 100644
--- a/3party/boost/boost/geometry/algorithms/simplify.hpp
+++ b/3party/boost/boost/geometry/algorithms/simplify.hpp
@@ -1,8 +1,8 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -16,9 +16,11 @@
#include <cstddef>
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/cs.hpp>
@@ -32,6 +34,7 @@
#include <boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp>
#include <boost/geometry/strategies/concepts/simplify_concept.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/algorithms/convert.hpp>
@@ -52,6 +55,8 @@ struct simplify_range_insert
static inline void apply(Range const& range, OutputIterator out,
Distance const& max_distance, Strategy const& strategy)
{
+ boost::ignore_unused(strategy);
+
if (boost::size(range) <= 2 || max_distance < 0)
{
std::copy(boost::begin(range), boost::end(range), out);
diff --git a/3party/boost/boost/geometry/algorithms/touches.hpp b/3party/boost/boost/geometry/algorithms/touches.hpp
index a06071d428..d6f0df3c74 100644
--- a/3party/boost/boost/geometry/algorithms/touches.hpp
+++ b/3party/boost/boost/geometry/algorithms/touches.hpp
@@ -23,6 +23,10 @@
#include <deque>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/detail/for_each_range.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
@@ -32,11 +36,9 @@
#include <boost/geometry/algorithms/num_geometries.hpp>
#include <boost/geometry/algorithms/detail/sub_range.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/variant/apply_visitor.hpp>
-#include <boost/variant/variant_fwd.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
namespace boost { namespace geometry
{
@@ -66,7 +68,7 @@ struct box_box_loop
coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
// TODO assert or exception?
- //BOOST_ASSERT(min1 <= max1 && min2 <= max2);
+ //BOOST_GEOMETRY_ASSERT(min1 <= max1 && min2 <= max2);
if ( max1 < min2 || max2 < min1 )
{
@@ -348,9 +350,9 @@ struct touches<Box1, Box2, box_tag, box_tag, areal_tag, areal_tag, false>
template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
struct touches<Linear1, Linear2, Tag1, Tag2, linear_tag, linear_tag, false>
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_touches_type,
+ detail::de9im::static_mask_touches_type,
Linear1,
Linear2
>
@@ -360,9 +362,9 @@ struct touches<Linear1, Linear2, Tag1, Tag2, linear_tag, linear_tag, false>
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, false>
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_touches_type,
+ detail::de9im::static_mask_touches_type,
Linear,
Areal
>
@@ -371,9 +373,9 @@ struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, false>
// A/L
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, true>
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_touches_type,
+ detail::de9im::static_mask_touches_type,
Areal,
Linear
>
diff --git a/3party/boost/boost/geometry/algorithms/transform.hpp b/3party/boost/boost/geometry/algorithms/transform.hpp
index 1d6e8d0a35..357263a4ea 100644
--- a/3party/boost/boost/geometry/algorithms/transform.hpp
+++ b/3party/boost/boost/geometry/algorithms/transform.hpp
@@ -20,8 +20,9 @@
#include <boost/range.hpp>
#include <boost/type_traits/remove_reference.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/assign.hpp>
diff --git a/3party/boost/boost/geometry/algorithms/union.hpp b/3party/boost/boost/geometry/algorithms/union.hpp
index bfd0ab3ba1..ff16c60ea1 100644
--- a/3party/boost/boost/geometry/algorithms/union.hpp
+++ b/3party/boost/boost/geometry/algorithms/union.hpp
@@ -179,68 +179,6 @@ struct union_insert
namespace detail { namespace union_
{
-template
-<
- typename GeometryOut,
- typename Geometry1, typename Geometry2,
- typename RobustPolicy,
- typename OutputIterator,
- typename Strategy
->
-inline OutputIterator insert(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- RobustPolicy const& robust_policy,
- OutputIterator out,
- Strategy const& strategy)
-{
- return dispatch::union_insert
- <
- Geometry1, Geometry2, GeometryOut
- >::apply(geometry1, geometry2, robust_policy, 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>();
-
- typedef typename Strategy::rescale_policy_type rescale_policy_type;
- rescale_policy_type robust_policy
- = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
-
- return detail::union_::insert<GeometryOut>(geometry1, geometry2, robust_policy, out, strategy);
-}
-
/*!
\brief_calc2{union}
\ingroup union
@@ -285,7 +223,13 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
rescale_policy_type
> strategy;
- return union_insert<GeometryOut>(geometry1, geometry2, out, strategy());
+ rescale_policy_type robust_policy
+ = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
+
+ return dispatch::union_insert
+ <
+ Geometry1, Geometry2, GeometryOut
+ >::apply(geometry1, geometry2, robust_policy, out, strategy());
}
diff --git a/3party/boost/boost/geometry/algorithms/validity_failure_type.hpp b/3party/boost/boost/geometry/algorithms/validity_failure_type.hpp
new file mode 100644
index 0000000000..42de99c585
--- /dev/null
+++ b/3party/boost/boost/geometry/algorithms/validity_failure_type.hpp
@@ -0,0 +1,87 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_VALIDITY_FAILURE_TYPE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_VALIDITY_FAILURE_TYPE_HPP
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+\brief Enumerates the possible validity failure types for a geometry
+\ingroup enum
+\details The enumeration validity_failure_type enumerates the possible
+ reasons for which a geometry may be found as invalid by the
+ is_valid algorithm.
+ Besides the values that indicate invalidity, there is an
+ additional value (no_failure) that indicates validity.
+
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.is_valid The is_valid
+algorithm taking a reference to validity_failure_type as second argument]
+}
+*/
+enum validity_failure_type
+{
+ /// The geometry is valid
+ ///
+ no_failure = 0,
+ /// The geometry has a very small number of points, e.g., less
+ /// than 2 for linestrings, less than 3 for open rings, a closed
+ /// multi-polygon that contains a polygon with less than 4 points, etc.
+ /// (applies to linestrings, rings, polygons, multi-linestrings
+ /// and multi-polygons)
+ failure_few_points = 10,
+ /// The topological dimension of the geometry is smaller than its
+ /// dimension, e.g., a linestring with 3 identical points, an open
+ /// polygon with an interior ring consisting of 3 collinear points, etc.
+ /// (applies to linear and areal geometries, including segments
+ /// and boxes)
+ failure_wrong_topological_dimension = 11,
+ /// The geometry contains spikes
+ /// (applies to linear and areal geometries)
+ failure_spikes = 12,
+ /// The geometry has (consecutive) duplicate points
+ /// (applies to areal geometries only)
+ failure_duplicate_points = 13,
+ /// The geometry is defined as closed, the starting/ending points
+ /// are not equal
+ /// (applies to areal geometries only)
+ failure_not_closed = 20, // for areal geometries
+ /// The geometry has invalid self-intersections.
+ /// (applies to areal geometries only)
+ failure_self_intersections = 21, // for areal geometries
+ /// The actual orientation of the geometry is different from the one defined
+ /// (applies to areal geometries only)
+ failure_wrong_orientation = 22, // for areal geometries
+ /// The geometry contains interior rings that lie outside the exterior ring
+ /// (applies to polygons and multi-polygons only)
+ failure_interior_rings_outside = 30, // for (multi-)polygons
+ /// The geometry has nested interior rings
+ /// (applies to polygons and multi-polygons only)
+ failure_nested_interior_rings = 31, // for (multi-)polygons
+ /// The interior of the geometry is disconnected
+ /// (applies to polygons and multi-polygons only)
+ failure_disconnected_interior = 32, // for (multi-)polygons
+ /// The multi-polygon contains polygons whose interiors are not disjoint
+ /// (applies to multi-polygons only)
+ failure_intersecting_interiors = 40, // for multi-polygons
+ /// The top-right corner of the box is lexicographically smaller
+ /// than its bottom-left corner
+ /// (applies to boxes only)
+ failure_wrong_corner_order = 50 // for boxes
+};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_VALIDITY_FAILURE_TYPE_HPP
diff --git a/3party/boost/boost/geometry/algorithms/within.hpp b/3party/boost/boost/geometry/algorithms/within.hpp
index f66b1ed1c6..9f2b6fedf7 100644
--- a/3party/boost/boost/geometry/algorithms/within.hpp
+++ b/3party/boost/boost/geometry/algorithms/within.hpp
@@ -24,8 +24,9 @@
#include <boost/concept_check.hpp>
#include <boost/range.hpp>
-#include <boost/variant/static_visitor.hpp>
+
#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/make.hpp>
diff --git a/3party/boost/boost/geometry/arithmetic/arithmetic.hpp b/3party/boost/boost/geometry/arithmetic/arithmetic.hpp
index 6eb31f488e..fbc3ca443e 100644
--- a/3party/boost/boost/geometry/arithmetic/arithmetic.hpp
+++ b/3party/boost/boost/geometry/arithmetic/arithmetic.hpp
@@ -22,6 +22,7 @@
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/util/for_each_coordinate.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
@@ -32,80 +33,94 @@ namespace detail
{
-template <typename P>
+template <typename Point>
struct param
{
typedef typename boost::call_traits
<
- typename coordinate_type<P>::type
+ typename coordinate_type<Point>::type
>::param_type type;
};
-template <typename C, template <typename> class Function>
+template <typename Value, template <typename> class Function>
struct value_operation
{
- C m_value;
+ Value m_value;
- inline value_operation(C const &value)
+ inline value_operation(Value const &value)
: m_value(value)
{}
- template <typename P, int I>
- inline void apply(P& point) const
+ template <typename PointDst, std::size_t Index>
+ inline void apply(PointDst& point_dst) const
{
- set<I>(point, Function<C>()(get<I>(point), m_value));
+ set<Index>(point_dst,
+ Function
+ <
+ typename geometry::select_most_precise
+ <
+ Value,
+ typename geometry::coordinate_type<PointDst>::type
+ >::type
+ >()(get<Index>(point_dst), 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;
+ PointSrc const& m_point_src;
inline point_operation(PointSrc const& point)
- : m_source_point(point)
+ : m_point_src(point)
{}
- template <typename PointDst, int I>
- inline void apply(PointDst& dest_point) const
+ template <typename PointDst, std::size_t Index>
+ inline void apply(PointDst& point_dst) const
{
- set<I>(dest_point,
- Function<coordinate_type>()(get<I>(dest_point), get<I>(m_source_point)));
+ set<Index>(point_dst,
+ Function
+ <
+ typename geometry::select_most_precise
+ <
+ typename geometry::coordinate_type<PointSrc>::type,
+ typename geometry::coordinate_type<PointDst>::type
+ >::type
+ >()(get<Index>(point_dst), get<Index>(m_point_src)));
}
};
-template <typename C>
+template <typename Value>
struct value_assignment
{
- C m_value;
+ Value m_value;
- inline value_assignment(C const &value)
+ inline value_assignment(Value const &value)
: m_value(value)
{}
- template <typename P, int I>
- inline void apply(P& point) const
+ template <typename PointDst, std::size_t Index>
+ inline void apply(PointDst& point_dst) const
{
- set<I>(point, m_value);
+ set<Index>(point_dst, m_value);
}
};
template <typename PointSrc>
struct point_assignment
{
- PointSrc const& m_source_point;
+ PointSrc const& m_point_src;
inline point_assignment(PointSrc const& point)
- : m_source_point(point)
+ : m_point_src(point)
{}
- template <typename PointDst, int I>
- inline void apply(PointDst& dest_point) const
+ template <typename PointDst, std::size_t Index>
+ inline void apply(PointDst& point_dst) const
{
- set<I>(dest_point, get<I>(m_source_point));
+ set<Index>(point_dst, get<Index>(m_point_src));
}
};
@@ -126,7 +141,12 @@ 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));
+ for_each_coordinate(p,
+ detail::value_operation
+ <
+ typename coordinate_type<Point>::type,
+ std::plus
+ >(value));
}
/*!
@@ -161,7 +181,12 @@ 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));
+ for_each_coordinate(p,
+ detail::value_operation
+ <
+ typename coordinate_type<Point>::type,
+ std::minus
+ >(value));
}
/*!
@@ -196,7 +221,12 @@ 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));
+ for_each_coordinate(p,
+ detail::value_operation
+ <
+ typename coordinate_type<Point>::type,
+ std::multiplies
+ >(value));
}
/*!
@@ -232,7 +262,12 @@ 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));
+ for_each_coordinate(p,
+ detail::value_operation
+ <
+ typename coordinate_type<Point>::type,
+ std::divides
+ >(value));
}
/*!
@@ -267,7 +302,11 @@ 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));
+ for_each_coordinate(p,
+ detail::value_assignment
+ <
+ typename coordinate_type<Point>::type
+ >(value));
}
/*!
diff --git a/3party/boost/boost/geometry/core/assert.hpp b/3party/boost/boost/geometry/core/assert.hpp
new file mode 100644
index 0000000000..0f3ae6baea
--- /dev/null
+++ b/3party/boost/boost/geometry/core/assert.hpp
@@ -0,0 +1,43 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
+// Copyright (c) 2007, 2014 Peter Dimov
+// Copyright (c) Beman Dawes 2011
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ASSERT_HPP
+#define BOOST_GEOMETRY_CORE_ASSERT_HPP
+
+#include <boost/assert.hpp>
+
+#undef BOOST_GEOMETRY_ASSERT
+#undef BOOST_GEOMETRY_ASSERT_MSG
+
+#if defined(BOOST_GEOMETRY_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_GEOMETRY_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) )
+
+#include <boost/config.hpp> // for BOOST_LIKELY
+#include <boost/current_function.hpp>
+
+namespace boost { namespace geometry
+{
+ void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined
+ void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line); // user defined
+}} // namespace boost::geometry
+
+#define BOOST_GEOMETRY_ASSERT(expr) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::geometry::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
+#define BOOST_GEOMETRY_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::geometry::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
+
+#else
+
+#define BOOST_GEOMETRY_ASSERT(expr) BOOST_ASSERT(expr)
+#define BOOST_GEOMETRY_ASSERT_MSG(expr, msg) BOOST_ASSERT_MSG(expr, msg)
+
+#endif
+
+#endif // BOOST_GEOMETRY_CORE_EXCEPTION_HPP
diff --git a/3party/boost/boost/geometry/core/closure.hpp b/3party/boost/boost/geometry/core/closure.hpp
index b61e352e93..b69dcda140 100644
--- a/3party/boost/boost/geometry/core/closure.hpp
+++ b/3party/boost/boost/geometry/core/closure.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -186,7 +191,7 @@ struct closure
static const closure_selector value = core_dispatch::closure
<
typename tag<Geometry>::type,
- typename boost::remove_const<Geometry>::type
+ typename util::bare_type<Geometry>::type
>::value;
};
diff --git a/3party/boost/boost/geometry/core/coordinate_dimension.hpp b/3party/boost/boost/geometry/core/coordinate_dimension.hpp
index 15df129deb..85da6b424e 100644
--- a/3party/boost/boost/geometry/core/coordinate_dimension.hpp
+++ b/3party/boost/boost/geometry/core/coordinate_dimension.hpp
@@ -58,7 +58,15 @@ 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<typename geometry::util::bare_type<P>::type> {};
+struct dimension<point_tag, P>
+ : traits::dimension<typename geometry::util::bare_type<P>::type>
+{
+ BOOST_MPL_ASSERT_MSG(
+ (traits::dimension<typename geometry::util::bare_type<P>::type>::value > 0),
+ INVALID_DIMENSION_VALUE,
+ (traits::dimension<typename geometry::util::bare_type<P>::type>)
+ );
+};
} // namespace core_dispatch
#endif
@@ -89,7 +97,7 @@ inline void assert_dimension()
BOOST_STATIC_ASSERT((
boost::mpl::equal_to
<
- geometry::dimension<Geometry>,
+ boost::mpl::int_<geometry::dimension<Geometry>::value>,
boost::mpl::int_<Dimensions>
>::type::value
));
@@ -102,13 +110,13 @@ inline void assert_dimension()
template <typename Geometry, int Dimensions>
inline void assert_dimension_less_equal()
{
- BOOST_STATIC_ASSERT(( dimension<Geometry>::type::value <= Dimensions ));
+ BOOST_STATIC_ASSERT(( static_cast<int>(dimension<Geometry>::type::value) <= Dimensions ));
}
template <typename Geometry, int Dimensions>
inline void assert_dimension_greater_equal()
{
- BOOST_STATIC_ASSERT(( dimension<Geometry>::type::value >= Dimensions ));
+ BOOST_STATIC_ASSERT(( static_cast<int>(dimension<Geometry>::type::value) >= Dimensions ));
}
/*!
@@ -118,7 +126,7 @@ inline void assert_dimension_greater_equal()
template <typename G1, typename G2>
inline void assert_dimension_equal()
{
- BOOST_STATIC_ASSERT(( dimension<G1>::type::value == dimension<G2>::type::value ));
+ BOOST_STATIC_ASSERT(( static_cast<size_t>(dimension<G1>::type::value) == static_cast<size_t>(dimension<G2>::type::value) ));
}
}} // namespace boost::geometry
diff --git a/3party/boost/boost/geometry/core/cs.hpp b/3party/boost/boost/geometry/core/cs.hpp
index cf6c56b53c..301fb6b76f 100644
--- a/3party/boost/boost/geometry/core/cs.hpp
+++ b/3party/boost/boost/geometry/core/cs.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -16,7 +21,8 @@
#include <cstddef>
-#include <boost/type_traits.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/integral_constant.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -45,6 +51,35 @@ struct degree {};
struct radian {};
+#ifndef DOXYGEN_NO_DETAIL
+namespace core_detail
+{
+
+template <typename DegreeOrRadian>
+struct coordinate_system_units
+{
+ BOOST_MPL_ASSERT_MSG
+ ((false),
+ COORDINATE_SYSTEM_UNITS_MUST_BE_DEGREES_OR_RADIANS,
+ (types<DegreeOrRadian>));
+};
+
+template <>
+struct coordinate_system_units<geometry::degree>
+{
+ typedef geometry::degree units;
+};
+
+template <>
+struct coordinate_system_units<geometry::radian>
+{
+ typedef geometry::radian units;
+};
+
+} // namespace core_detail
+#endif // DOXYGEN_NO_DETAIL
+
+
namespace cs
{
@@ -73,7 +108,10 @@ known as lat,long or lo,la or phi,lambda
template<typename DegreeOrRadian>
struct geographic
{
- typedef DegreeOrRadian units;
+ typedef typename core_detail::coordinate_system_units
+ <
+ DegreeOrRadian
+ >::units units;
};
@@ -99,7 +137,10 @@ struct geographic
template<typename DegreeOrRadian>
struct spherical
{
- typedef DegreeOrRadian units;
+ typedef typename core_detail::coordinate_system_units
+ <
+ DegreeOrRadian
+ >::units units;
};
@@ -116,7 +157,10 @@ struct spherical
template<typename DegreeOrRadian>
struct spherical_equatorial
{
- typedef DegreeOrRadian units;
+ typedef typename core_detail::coordinate_system_units
+ <
+ DegreeOrRadian
+ >::units units;
};
@@ -131,7 +175,10 @@ struct spherical_equatorial
template<typename DegreeOrRadian>
struct polar
{
- typedef DegreeOrRadian units;
+ typedef typename core_detail::coordinate_system_units
+ <
+ DegreeOrRadian
+ >::units units;
};
diff --git a/3party/boost/boost/geometry/core/exception.hpp b/3party/boost/boost/geometry/core/exception.hpp
index 97d249e938..6868ca775a 100644
--- a/3party/boost/boost/geometry/core/exception.hpp
+++ b/3party/boost/boost/geometry/core/exception.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -26,8 +31,31 @@ namespace boost { namespace geometry
are derived from exception, so it might be convenient to catch it.
*/
class exception : public std::exception
-{};
+{
+ virtual char const* what() const throw()
+ {
+ return "Boost.Geometry exception";
+ }
+};
+
+/*!
+\brief Invalid Input Exception
+\ingroup core
+\details The invalid_input_exception is thrown if an invalid attribute
+ is passed into a function, e.g. a DE-9IM mask string code containing
+ invalid characters passed into a de9im::mask constructor.
+ */
+class invalid_input_exception : public geometry::exception
+{
+public:
+
+ inline invalid_input_exception() {}
+ virtual char const* what() const throw()
+ {
+ return "Boost.Geometry Invalid-Input exception";
+ }
+};
/*!
\brief Empty Input Exception
@@ -42,7 +70,7 @@ class exception : public std::exception
\* [link geometry.reference.algorithms.length the length function]
}
*/
-class empty_input_exception : public geometry::exception
+class empty_input_exception : public geometry::invalid_input_exception
{
public:
diff --git a/3party/boost/boost/geometry/core/interior_type.hpp b/3party/boost/boost/geometry/core/interior_type.hpp
index 02328372f0..e6c4537e41 100644
--- a/3party/boost/boost/geometry/core/interior_type.hpp
+++ b/3party/boost/boost/geometry/core/interior_type.hpp
@@ -86,7 +86,7 @@ struct interior_return_type<polygon_tag, Polygon>
{
typedef typename boost::remove_const<Polygon>::type nc_polygon_type;
- typedef typename mpl::if_
+ typedef typename boost::mpl::if_
<
boost::is_const<Polygon>,
typename traits::interior_const_type<nc_polygon_type>::type,
diff --git a/3party/boost/boost/geometry/core/point_order.hpp b/3party/boost/boost/geometry/core/point_order.hpp
index 501dda777b..d43adbd03a 100644
--- a/3party/boost/boost/geometry/core/point_order.hpp
+++ b/3party/boost/boost/geometry/core/point_order.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -173,7 +178,7 @@ struct point_order
static const order_selector value = core_dispatch::point_order
<
typename tag<Geometry>::type,
- typename boost::remove_const<Geometry>::type
+ typename util::bare_type<Geometry>::type
>::value;
};
diff --git a/3party/boost/boost/geometry/core/radian_access.hpp b/3party/boost/boost/geometry/core/radian_access.hpp
index bac77d7bc7..374c2954a2 100644
--- a/3party/boost/boost/geometry/core/radian_access.hpp
+++ b/3party/boost/boost/geometry/core/radian_access.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -47,7 +52,8 @@ struct degree_radian_converter
return boost::numeric_cast
<
coordinate_type
- >(geometry::get<Dimension>(geometry) * geometry::math::d2r);
+ >(geometry::get<Dimension>(geometry)
+ * math::d2r<coordinate_type>());
}
static inline void set(Geometry& geometry, coordinate_type const& radians)
@@ -55,7 +61,7 @@ struct degree_radian_converter
geometry::set<Dimension>(geometry, boost::numeric_cast
<
coordinate_type
- >(radians * geometry::math::r2d));
+ >(radians * math::r2d<coordinate_type>()));
}
};
diff --git a/3party/boost/boost/geometry/core/radius.hpp b/3party/boost/boost/geometry/core/radius.hpp
new file mode 100644
index 0000000000..ee6d5d246f
--- /dev/null
+++ b/3party/boost/boost/geometry/core/radius.hpp
@@ -0,0 +1,250 @@
+// 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.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_RADIUS_HPP
+#define BOOST_GEOMETRY_CORE_RADIUS_HPP
+
+
+#include <cstddef>
+
+#include <boost/static_assert.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/util/bare_type.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(Geometry const& geometry)
+ - inline static void set(Geometry& geometry, T const& radius)
+ \ingroup traits
+*/
+template <typename Geometry, std::size_t Dimension>
+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 Geometry>
+struct radius_type {};
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Tag, typename Geometry>
+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 Geometry,
+ std::size_t Dimension,
+ typename IsPointer>
+struct radius_access
+{
+ //static inline CoordinateType get(Geometry const& ) {}
+ //static inline void set(Geometry& g, CoordinateType const& value) {}
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief Metafunction to get the type of radius of a circle / sphere / ellipse / etc.
+ \ingroup access
+ \tparam Geometry the type of geometry
+*/
+template <typename Geometry>
+struct radius_type
+{
+ typedef typename core_dispatch::radius_type
+ <
+ typename tag<Geometry>::type,
+ typename util::bare_type<Geometry>::type
+ >::type type;
+};
+
+/*!
+ \brief Function to get radius of a circle / sphere / ellipse / etc.
+ \return radius The radius for a given axis
+ \ingroup access
+ \param geometry the geometry to get the radius from
+ \tparam I index of the axis
+*/
+template <std::size_t I, typename Geometry>
+inline typename radius_type<Geometry>::type get_radius(Geometry const& geometry)
+{
+ return core_dispatch::radius_access
+ <
+ typename tag<Geometry>::type,
+ typename util::bare_type<Geometry>::type,
+ I,
+ typename boost::is_pointer<Geometry>::type
+ >::get(geometry);
+}
+
+/*!
+ \brief Function to set the radius of a circle / sphere / ellipse / etc.
+ \ingroup access
+ \tparam I index of the axis
+ \param geometry the geometry to change
+ \param radius the radius to set
+*/
+template <std::size_t I, typename Geometry>
+inline void set_radius(Geometry& geometry,
+ typename radius_type<Geometry>::type const& radius)
+{
+ core_dispatch::radius_access
+ <
+ typename tag<Geometry>::type,
+ typename util::bare_type<Geometry>::type,
+ I,
+ typename boost::is_pointer<Geometry>::type
+ >::set(geometry, radius);
+}
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Tag, typename Geometry, std::size_t Dimension>
+struct radius_access
+{
+ static inline typename radius_type<Geometry>::type get(Geometry const& geometry)
+ {
+ return traits::radius_access<Geometry, Dimension>::get(geometry);
+ }
+ static inline void set(Geometry& geometry,
+ typename radius_type<Geometry>::type const& value)
+ {
+ traits::radius_access<Geometry, Dimension>::set(geometry, value);
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Tag,
+ typename Geometry,
+ std::size_t Dimension>
+struct radius_access<Tag, Geometry, Dimension, boost::true_type>
+{
+ typedef typename geometry::radius_type<Geometry>::type radius_type;
+
+ static inline radius_type get(const Geometry * geometry)
+ {
+ return radius_access
+ <
+ Tag,
+ Geometry,
+ Dimension,
+ typename boost::is_pointer<Geometry>::type
+ >::get(*geometry);
+ }
+
+ static inline void set(Geometry * geometry, radius_type const& value)
+ {
+ return radius_access
+ <
+ Tag,
+ Geometry,
+ Dimension,
+ typename boost::is_pointer<Geometry>::type
+ >::set(*geometry, value);
+ }
+};
+
+
+template <typename Geometry>
+struct radius_type<srs_sphere_tag, Geometry>
+{
+ typedef typename traits::radius_type<Geometry>::type type;
+};
+
+template <typename Geometry, std::size_t Dimension>
+struct radius_access<srs_sphere_tag, Geometry, Dimension, boost::false_type>
+ : detail::radius_access<srs_sphere_tag, Geometry, Dimension>
+{
+ BOOST_STATIC_ASSERT(Dimension == 0);
+ //BOOST_STATIC_ASSERT(Dimension < 3);
+};
+
+template <typename Geometry>
+struct radius_type<srs_spheroid_tag, Geometry>
+{
+ typedef typename traits::radius_type<Geometry>::type type;
+};
+
+template <typename Geometry, std::size_t Dimension>
+struct radius_access<srs_spheroid_tag, Geometry, Dimension, boost::false_type>
+ : detail::radius_access<srs_spheroid_tag, Geometry, Dimension>
+{
+ BOOST_STATIC_ASSERT(Dimension == 0 || Dimension == 2);
+ //BOOST_STATIC_ASSERT(Dimension < 3);
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_RADIUS_HPP
diff --git a/3party/boost/boost/geometry/core/ring_type.hpp b/3party/boost/boost/geometry/core/ring_type.hpp
index fe551f060f..c007931126 100644
--- a/3party/boost/boost/geometry/core/ring_type.hpp
+++ b/3party/boost/boost/geometry/core/ring_type.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -95,7 +100,7 @@ struct ring_return_type<polygon_tag, Polygon>
{
typedef typename boost::remove_const<Polygon>::type nc_polygon_type;
- typedef typename mpl::if_
+ typedef typename boost::mpl::if_
<
boost::is_const<Polygon>,
typename traits::ring_const_type<nc_polygon_type>::type,
@@ -110,7 +115,7 @@ struct ring_return_type<multi_linestring_tag, MultiLinestring>
typedef typename ring_return_type
<
linestring_tag,
- typename mpl::if_
+ typename boost::mpl::if_
<
boost::is_const<MultiLinestring>,
typename boost::range_value<MultiLinestring>::type const,
@@ -126,7 +131,7 @@ struct ring_return_type<multi_polygon_tag, MultiPolygon>
typedef typename ring_return_type
<
polygon_tag,
- typename mpl::if_
+ typename boost::mpl::if_
<
boost::is_const<MultiPolygon>,
typename boost::range_value<MultiPolygon>::type const,
diff --git a/3party/boost/boost/geometry/core/srs.hpp b/3party/boost/boost/geometry/core/srs.hpp
new file mode 100644
index 0000000000..bf1b4e28a5
--- /dev/null
+++ b/3party/boost/boost/geometry/core/srs.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.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_SRS_HPP
+#define BOOST_GEOMETRY_CORE_SRS_HPP
+
+
+#include <cstddef>
+
+#include <boost/static_assert.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace srs
+{
+
+/*!
+ \brief Defines spheroid radius values for use in geographical CS calculations
+ \note 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
+*/
+template <typename RadiusType>
+class spheroid
+{
+public:
+ spheroid(RadiusType const& a, RadiusType const& b)
+ : m_a(a)
+ , m_b(b)
+ {}
+
+ spheroid()
+ : m_a(RadiusType(6378137.0))
+ , m_b(RadiusType(6356752.314245))
+ {}
+
+ template <std::size_t I>
+ RadiusType get_radius() const
+ {
+ BOOST_STATIC_ASSERT(I < 3);
+
+ return I < 2 ? m_a : m_b;
+ }
+
+ template <std::size_t I>
+ void set_radius(RadiusType const& radius)
+ {
+ BOOST_STATIC_ASSERT(I < 3);
+
+ (I < 2 ? m_a : m_b) = radius;
+ }
+
+private:
+ RadiusType m_a, m_b; // equatorial radius, polar radius
+};
+
+} // namespace srs
+
+// Traits specializations for spheroid
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename RadiusType>
+struct tag< srs::spheroid<RadiusType> >
+{
+ typedef srs_spheroid_tag type;
+};
+
+template <typename RadiusType>
+struct radius_type< srs::spheroid<RadiusType> >
+{
+ typedef RadiusType type;
+};
+
+template <typename RadiusType, std::size_t Dimension>
+struct radius_access<srs::spheroid<RadiusType>, Dimension>
+{
+ typedef srs::spheroid<RadiusType> spheroid_type;
+
+ static inline RadiusType get(spheroid_type const& s)
+ {
+ return s.template get_radius<Dimension>();
+ }
+
+ static inline void set(spheroid_type& s, RadiusType const& value)
+ {
+ s.template set_radius<Dimension>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+namespace srs
+{
+
+/*!
+ \brief Defines sphere radius value for use in spherical CS calculations
+*/
+template <typename RadiusType>
+class sphere
+{
+public:
+ explicit sphere(RadiusType const& r)
+ : m_r(r)
+ {}
+ sphere()
+ : m_r(RadiusType((2.0 * 6378137.0 + 6356752.314245) / 3.0))
+ {}
+
+ template <std::size_t I>
+ RadiusType get_radius() const
+ {
+ BOOST_STATIC_ASSERT(I < 3);
+
+ return m_r;
+ }
+
+ template <std::size_t I>
+ void set_radius(RadiusType const& radius)
+ {
+ BOOST_STATIC_ASSERT(I < 3);
+
+ m_r = radius;
+ }
+
+private:
+ RadiusType m_r; // radius
+};
+
+} // namespace srs
+
+// Traits specializations for sphere
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename RadiusType>
+struct tag< srs::sphere<RadiusType> >
+{
+ typedef srs_sphere_tag type;
+};
+
+template <typename RadiusType>
+struct radius_type< srs::sphere<RadiusType> >
+{
+ typedef RadiusType type;
+};
+
+template <typename RadiusType, std::size_t Dimension>
+struct radius_access<srs::sphere<RadiusType>, Dimension>
+{
+ typedef srs::sphere<RadiusType> sphere_type;
+
+ static inline RadiusType get(sphere_type const& s)
+ {
+ return s.template get_radius<Dimension>();
+ }
+
+ static inline void set(sphere_type& s, RadiusType const& value)
+ {
+ s.template set_radius<Dimension>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_SRS_HPP
diff --git a/3party/boost/boost/geometry/core/tags.hpp b/3party/boost/boost/geometry/core/tags.hpp
index 160477b8c4..5d6acb1878 100644
--- a/3party/boost/boost/geometry/core/tags.hpp
+++ b/3party/boost/boost/geometry/core/tags.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -37,6 +42,14 @@ struct spherical_equatorial_tag : spherical_tag {};
struct geographic_tag : spherical_tag {};
+// Tags defining coordinate systems reference models
+
+/// For reference spheroid defining parameters of geographical coordinate system
+struct srs_spheroid_tag {};
+
+/// For reference sphere defining parameters of spherical coordinate system
+struct srs_sphere_tag : srs_spheroid_tag {};
+
// Tags defining tag hierarchy
diff --git a/3party/boost/boost/geometry/extensions/algebra/algebra.hpp b/3party/boost/boost/geometry/extensions/algebra/algebra.hpp
new file mode 100644
index 0000000000..1677576872
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/algebra.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_ALGEBRA_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGEBRA_HPP
+
+#include <boost/geometry/extensions/algebra/core/access.hpp>
+#include <boost/geometry/extensions/algebra/core/coordinate_dimension.hpp>
+#include <boost/geometry/extensions/algebra/core/coordinate_system.hpp>
+#include <boost/geometry/extensions/algebra/core/coordinate_type.hpp>
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+
+#include <boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/check.hpp>
+
+#include <boost/geometry/extensions/algebra/geometries/vector.hpp>
+#include <boost/geometry/extensions/algebra/geometries/rotation_quaternion.hpp>
+#include <boost/geometry/extensions/algebra/geometries/rotation_matrix.hpp>
+
+#include <boost/geometry/extensions/algebra/algorithms/assign.hpp>
+#include <boost/geometry/extensions/algebra/algorithms/convert.hpp>
+
+// experimental
+#include <boost/geometry/extensions/algebra/algorithms/clear.hpp>
+#include <boost/geometry/extensions/algebra/algorithms/reverse.hpp>
+
+#include <boost/geometry/extensions/algebra/algorithms/translation.hpp>
+#include <boost/geometry/extensions/algebra/algorithms/rotation.hpp>
+
+// should be removed, transform() should be used instead
+#include <boost/geometry/extensions/algebra/algorithms/transform_geometrically.hpp>
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGEBRA_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/algorithms/assign.hpp b/3party/boost/boost/geometry/extensions/algebra/algorithms/assign.hpp
new file mode 100644
index 0000000000..d25785de78
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/algorithms/assign.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_ALGORITHMS_ASSIGN_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_ASSIGN_HPP
+
+#include <boost/geometry/algorithms/assign.hpp>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+
+#include <boost/geometry/extensions/algebra/algorithms/detail.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Vector>
+struct assign_zero<vector_tag, Vector>
+{
+ static inline void apply(Vector & g)
+ {
+ detail::algebra::assign_value<
+ Vector,
+ typename coordinate_type<Vector>::type,
+ 0, dimension<Vector>::type::value
+ >::apply(g, 0);
+ }
+};
+
+template <typename GeometryTag, typename Geometry>
+struct assign_identity
+{
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (GeometryTag, Geometry));
+};
+
+template <typename R>
+struct assign_identity<rotation_quaternion_tag, R>
+{
+ static inline void apply(R & g)
+ {
+ set<0>(g, 1); set<1>(g, 0); set<2>(g, 0); set<3>(g, 0);
+ }
+};
+
+template <typename R>
+struct assign_identity<rotation_matrix_tag, R>
+{
+ static inline void apply(R & r)
+ {
+ detail::algebra::identity_matrix<
+ R, 0, 0, dimension<R>::value, dimension<R>::value
+ >::apply(r);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+// TODO
+// Use assign_zero for initialization of 0-angle rotation instead of assign_identity?
+
+/*!
+\brief assign identity to Transformation
+\ingroup assign
+\details The assign_identity function initializes a rotation or transformation with values indicating no rotation
+\tparam Rotation The rotation type.
+\param rotation The rotation.
+ */
+template <typename Rotation>
+inline void assign_identity(Rotation & rotation)
+{
+ concept::check<Rotation>();
+
+ dispatch::assign_identity<
+ typename tag<Rotation>::type,
+ Rotation
+ >::apply(rotation);
+}
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename V>
+struct assign<vector_tag, V, 2>
+{
+ typedef typename coordinate_type<V>::type coordinate_type;
+
+ template <typename T>
+ static inline void apply(V& v, T const& c1, T const& c2)
+ {
+ set<0>(v, boost::numeric_cast<coordinate_type>(c1));
+ set<1>(v, boost::numeric_cast<coordinate_type>(c2));
+ }
+};
+
+template <typename V>
+struct assign<vector_tag, V, 3>
+{
+ typedef typename coordinate_type<V>::type coordinate_type;
+
+ template <typename T>
+ static inline void apply(V& v, T const& c1, T const& c2, T const& c3)
+ {
+ set<0>(v, boost::numeric_cast<coordinate_type>(c1));
+ set<1>(v, boost::numeric_cast<coordinate_type>(c2));
+ set<2>(v, boost::numeric_cast<coordinate_type>(c3));
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_ASSIGN_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/algorithms/clear.hpp b/3party/boost/boost/geometry/extensions/algebra/algorithms/clear.hpp
new file mode 100644
index 0000000000..62618efcd9
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/algorithms/clear.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_ALGORITHMS_CLEAR_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_CLEAR_HPP
+
+#include <boost/geometry/algorithms/clear.hpp>
+
+#include <boost/geometry/extensions/algebra/algorithms/assign.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// This is experimental implementation of clear() which assigns zeros to vectors
+// and identities to rotations. It doesn't work for them as for Geometries.
+
+template <typename Vector>
+struct clear<Vector, vector_tag>
+{
+ static inline void apply(Vector & v)
+ {
+ geometry::assign_zero(v);
+ }
+};
+
+template <typename R>
+struct clear<R, rotation_quaternion_tag>
+{
+ static inline void apply(R & r)
+ {
+ geometry::assign_identity(r);
+ }
+};
+
+template <typename R>
+struct clear<R, rotation_matrix_tag>
+{
+ static inline void apply(R & r)
+ {
+ geometry::assign_identity(r);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_CLEAR_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/algorithms/convert.hpp b/3party/boost/boost/geometry/extensions/algebra/algorithms/convert.hpp
new file mode 100644
index 0000000000..593c050282
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/algorithms/convert.hpp
@@ -0,0 +1,87 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_ALGORITHMS_CONVERT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_CONVERT_HPP
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+
+#include <boost/geometry/extensions/algebra/algorithms/detail.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename RQuaternion, typename RMatrix>
+struct convert<RQuaternion, RMatrix, rotation_quaternion_tag, rotation_matrix_tag, 3, false>
+{
+ static inline void apply(RQuaternion const& q, RMatrix& m)
+ {
+ typedef typename coordinate_type<RQuaternion>::type T;
+
+ // quaternion should be normalized
+
+ T xx2 = get<1>(q) * get<1>(q) * 2;
+ T yy2 = get<2>(q) * get<2>(q) * 2;
+ T zz2 = get<3>(q) * get<3>(q) * 2;
+ T xy2 = get<1>(q) * get<2>(q) * 2;
+ T yz2 = get<2>(q) * get<3>(q) * 2;
+ T xz2 = get<1>(q) * get<3>(q) * 2;
+ T wx2 = get<0>(q) * get<1>(q) * 2;
+ T wy2 = get<0>(q) * get<2>(q) * 2;
+ T wz2 = get<0>(q) * get<3>(q) * 2;
+
+ // WARNING!
+ // Quaternion (0, 0, 0, 0) is converted to identity matrix!
+
+ set<0, 0>(m, 1-yy2-zz2); set<0, 1>(m, xy2-wz2); set<0, 2>(m, xz2+wy2);
+ set<1, 0>(m, xy2+wz2); set<1, 1>(m, 1-xx2-zz2); set<1, 2>(m, yz2-wx2);
+ set<2, 0>(m, xz2-wy2); set<2, 1>(m, yz2+wx2); set<2, 2>(m, 1-xx2-yy2);
+ }
+};
+
+template <typename RMatrix, typename RQuaternion>
+struct convert<RMatrix, RQuaternion, rotation_matrix_tag, rotation_quaternion_tag, 3, false>
+{
+ static inline void apply(RMatrix const& m, RQuaternion & q)
+ {
+ typedef typename coordinate_type<RMatrix>::type T;
+
+ // WARNING!
+ // Zero matrix is converted to quaternion(0.5, 0, 0, 0)!
+
+ T w = math::sqrt(1 + get<0, 0>(m) + get<1, 1>(m) + get<2, 2>(m)) / 2;
+ T iw4 = 0.25 / w;
+ set<0>(q, w);
+ set<1>(q, (get<2, 1>(m) - get<1, 2>(m)) * iw4);
+ set<2>(q, (get<0, 2>(m) - get<2, 0>(m)) * iw4);
+ set<3>(q, (get<1, 0>(m) - get<0, 1>(m)) * iw4);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_ASSIGN_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/algorithms/detail.hpp b/3party/boost/boost/geometry/extensions/algebra/algorithms/detail.hpp
new file mode 100644
index 0000000000..63c5bd9fa3
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/algorithms/detail.hpp
@@ -0,0 +1,356 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_ALGORITHMS_DETAIL_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_DETAIL_HPP
+
+// TODO - for multiplication of coordinates
+// if coordinate_type is_integral - use double as the result type
+
+#include <boost/geometry/util/math.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace algebra {
+
+// Cross 3D of 3 components of Vectors/Quaternion starting from IS1 and IS2 and placing the result starting from D
+template <std::size_t IS1, std::size_t IS2, std::size_t ID, typename S1, typename S2, typename D>
+inline void cross(S1 const& s1, S2 const& s2, D & d)
+{
+ set<ID+0>(d, get<IS1+1>(s1)*get<IS2+2>(s2) - get<IS1+2>(s1)*get<IS2+1>(s2));
+ set<ID+1>(d, get<IS1+2>(s1)*get<IS2+0>(s2) - get<IS1+0>(s1)*get<IS2+2>(s2));
+ set<ID+2>(d, get<IS1+0>(s1)*get<IS2+1>(s2) - get<IS1+1>(s1)*get<IS2+0>(s2));
+}
+
+// Dot of N components of Vectors/Quaternion starting from IS1 and IS2
+
+template <typename S1, typename S2, std::size_t IS1, std::size_t IS2, std::size_t N>
+struct dot_impl
+{
+ BOOST_STATIC_ASSERT(0 < N);
+
+ typedef typename geometry::select_most_precise<
+ typename traits::coordinate_type<S1>::type,
+ typename traits::coordinate_type<S2>::type
+ >::type coordinate_type;
+
+ static inline coordinate_type apply(S1 const& s1, S2 const& s2)
+ {
+ return get<IS1>(s1)*get<IS2>(s2) + dot_impl<S1, S2, IS1+1, IS2+1, N-1>::apply(s1, s2);
+ }
+};
+
+template <typename S1, typename S2, std::size_t IS1, std::size_t IS2>
+struct dot_impl<S1, S2, IS1, IS2, 1>
+{
+ typedef typename geometry::select_most_precise<
+ typename traits::coordinate_type<S1>::type,
+ typename traits::coordinate_type<S2>::type
+ >::type coordinate_type;
+
+ static inline coordinate_type apply(S1 const& s1, S2 const& s2)
+ {
+ return get<IS1>(s1)*get<IS2>(s2);
+ }
+};
+
+template <std::size_t IS1, std::size_t IS2, std::size_t N, typename S1, typename S2>
+inline static
+typename geometry::select_most_precise<
+ typename traits::coordinate_type<S1>::type,
+ typename traits::coordinate_type<S2>::type
+>::type
+dot(S1 const& s1, S2 const& s2)
+{
+ return dot_impl<S1, S2, IS1, IS2, N>::apply(s1, s2);
+}
+
+// Multiplication of N components starting from Ith by Value v
+
+template <typename S, typename T, std::size_t IS, std::size_t I, std::size_t N>
+struct mul_impl
+{
+ BOOST_STATIC_ASSERT(0 < N);
+
+ static inline void apply(S & s, T const& v)
+ {
+ set<IS>(s, get<IS>(s) * v);
+ mul_impl<S, T, IS+1, I+1, N>::apply(s, v);
+ }
+};
+
+template <typename S, typename T, std::size_t IS, std::size_t N>
+struct mul_impl<S, T, IS, N, N>
+{
+ static inline void apply(S &, T const&) {}
+};
+
+template <std::size_t IS, std::size_t N, typename S, typename T>
+inline static void mul(S & s, T const& v)
+{
+ return mul_impl<S, T, IS, 0, N>::apply(s, v);
+}
+
+// Negation
+
+template <typename V, std::size_t I, std::size_t N>
+struct neg_impl
+{
+ BOOST_STATIC_ASSERT(0 < N);
+
+ static inline void apply(V & v)
+ {
+ set<I>(v, -get<I>(v));
+ neg_impl<V, I+1, N>::apply(v);
+ }
+};
+
+template <typename V, std::size_t N>
+struct neg_impl<V, N, N>
+{
+ static inline void apply(V &) {}
+};
+
+template <std::size_t I, std::size_t N, typename V>
+inline static void neg(V & v)
+{
+ return neg_impl<V, I, N>::apply(v);
+}
+
+// Normalization of N components starting from Ith
+
+template <std::size_t I, std::size_t N, typename S>
+inline static void normalize(S & s)
+{
+ typedef typename traits::coordinate_type<S>::type T;
+
+ T lsqr = dot<I, I, N>(s, s);
+ if ( std::numeric_limits<T>::epsilon() < lsqr )
+ mul<I, N>(s, 1.0f / math::sqrt(lsqr));
+}
+
+// Square matrix * Vector of the same dimension
+
+template <typename M, typename V, typename VD, std::size_t I, std::size_t N>
+struct matrix_mul_row_impl
+{
+ BOOST_STATIC_ASSERT(0 < N);
+
+ static const std::size_t dimension = traits::dimension<M>::value;
+
+ static inline
+ typename traits::coordinate_type<VD>::type
+ apply(M const& m, V const& v)
+ {
+ return matrix_mul_row_impl<M, V, VD, I, N-1>::apply(m, v) + get<I, N-1>(m) * get<N-1>(v);
+ }
+};
+
+template <typename M, typename V, typename VD, std::size_t I>
+struct matrix_mul_row_impl<M, V, VD, I, 1>
+{
+ static const std::size_t dimension = traits::dimension<M>::value;
+
+ static inline
+ typename traits::coordinate_type<VD>::type
+ apply(M const& m, V const& v)
+ {
+ return get<I, 0>(m) * get<0>(v);
+ }
+};
+
+template <typename M, typename V, typename VD, std::size_t I, std::size_t N>
+struct matrix_mul_impl
+{
+ static inline void apply(M const& m, V const& v, VD & vd)
+ {
+ set<I>(vd, matrix_mul_row_impl<M, V, VD, I, N>::apply(m, v));
+ matrix_mul_impl<M, V, VD, I+1, N>::apply(m, v, vd);
+ }
+};
+
+template <typename M, typename V, typename VD, std::size_t N>
+struct matrix_mul_impl<M, V, VD, N, N>
+{
+ static inline void apply(M const&, V const&, VD &) {}
+};
+
+// Matrix rotation - M*V
+
+template <typename M, typename V, typename VD>
+inline static void matrix_rotate(M const& m, V const& v, VD & vd)
+{
+ static const std::size_t dimension = traits::dimension<M>::value;
+
+ matrix_mul_impl<M, V, VD, 0, dimension>::apply(m, v, vd);
+}
+
+// Quaternion rotation - Q*V*Q' - * is Hamilton product
+
+template <typename V, typename Q>
+inline static void quaternion_rotate(V & v, Q const& r)
+{
+ // TODO - choose more precise type?
+
+ typedef typename geometry::select_most_precise<
+ typename traits::coordinate_type<V>::type,
+ typename traits::coordinate_type<Q>::type
+ >::type T;
+
+ // Hamilton product T=Q*V
+ T a = /*get<0>(r) * 0 */- get<1>(r) * get<0>(v) - get<2>(r) * get<1>(v) - get<3>(r) * get<2>(v);
+ T b = get<0>(r) * get<0>(v)/* + get<1>(r) * 0*/ + get<2>(r) * get<2>(v) - get<3>(r) * get<1>(v);
+ T c = get<0>(r) * get<1>(v) - get<1>(r) * get<2>(v)/* + get<2>(r) * 0*/ + get<3>(r) * get<0>(v);
+ T d = get<0>(r) * get<2>(v) + get<1>(r) * get<1>(v) - get<2>(r) * get<0>(v)/* + get<3>(r) * 0*/;
+ // Hamilton product V=T*inv(Q)
+ set<0>(v, - a * get<1>(r) + b * get<0>(r) - c * get<3>(r) + d * get<2>(r));
+ set<1>(v, - a * get<2>(r) + b * get<3>(r) + c * get<0>(r) - d * get<1>(r));
+ set<2>(v, - a * get<3>(r) - b * get<2>(r) + c * get<1>(r) + d * get<0>(r));
+}
+
+// Assign value
+
+template <typename G, typename V, std::size_t B, std::size_t E>
+struct assign_value
+{
+ static inline void apply(G & g, V const& v)
+ {
+ set<B>(g, v);
+ assign_value<G, V, B+1, E>::apply(g, v);
+ }
+};
+
+template <typename G, typename V, std::size_t E>
+struct assign_value<G, V, E, E>
+{
+ static inline void apply(G &, V const&) {}
+};
+
+template <typename G, typename V, std::size_t BI, std::size_t BD, std::size_t EI, std::size_t ED>
+struct indexed_assign_value_per_index
+{
+ static inline void apply(G & g, V const& v)
+ {
+ set<BI, BD>(g, v);
+ indexed_assign_value_per_index<G, V, BI, BD+1, EI, ED>::apply(g, v);
+ }
+};
+
+// Assign value using indexed access
+
+template <typename G, typename V, std::size_t BI, std::size_t EI, std::size_t ED>
+struct indexed_assign_value_per_index<G, V, BI, ED, EI, ED>
+{
+ static inline void apply(G &, V const&) {}
+};
+
+template <typename G, typename V, std::size_t BI, std::size_t BD, std::size_t EI, std::size_t ED>
+struct indexed_assign_value
+{
+ static inline void apply(G & g, V const& v)
+ {
+ indexed_assign_value_per_index<G, V, BI, BD, EI, ED>::apply(g, v);
+ indexed_assign_value<G, V, BI+1, BD, EI, ED>::apply(g, v);
+ }
+};
+
+template <typename G, typename V, std::size_t BD, std::size_t EI, std::size_t ED>
+struct indexed_assign_value<G, V, EI, BD, EI, ED>
+{
+ static inline void apply(G &, V const&) {}
+};
+
+template <typename G, std::size_t BI, std::size_t BD, std::size_t EI, std::size_t ED>
+struct identity_matrix_per_index
+{
+ static inline void apply(G & g)
+ {
+ set<BI, BD>(g, 0);
+ identity_matrix_per_index<G, BI, BD+1, EI, ED>::apply(g);
+ }
+};
+
+// Identity matrix
+
+template <typename G, std::size_t BI, std::size_t EI, std::size_t ED>
+struct identity_matrix_per_index<G, BI, BI, EI, ED>
+{
+ static inline void apply(G & g)
+ {
+ set<BI, BI>(g, 1);
+ identity_matrix_per_index<G, BI, BI+1, EI, ED>::apply(g);
+ }
+};
+
+template <typename G, std::size_t BI, std::size_t EI, std::size_t ED>
+struct identity_matrix_per_index<G, BI, ED, EI, ED>
+{
+ static inline void apply(G &) {}
+};
+
+template <typename G, std::size_t BI, std::size_t BD, std::size_t EI, std::size_t ED>
+struct identity_matrix
+{
+ static inline void apply(G & g)
+ {
+ identity_matrix_per_index<G, BI, BD, EI, ED>::apply(g);
+ identity_matrix<G, BI+1, BD, EI, ED>::apply(g);
+ }
+};
+
+template <typename G, std::size_t BD, std::size_t EI, std::size_t ED>
+struct identity_matrix<G, EI, BD, EI, ED>
+{
+ static inline void apply(G &) {}
+};
+
+// Matrix transpose
+
+template <typename G, std::size_t I, std::size_t D, std::size_t N>
+struct matrix_transpose_per_index
+{
+ static inline void apply(G & g)
+ {
+ // swap coordinates
+ typename coordinate_type<G>::type tmp = get<I, D>(g);
+ set<I, D>(g, get<D, I>(g));
+ set<D, I>(g, tmp);
+ matrix_transpose_per_index<G, I, D+1, N>::apply(g);
+ }
+};
+
+template <typename G, std::size_t I, std::size_t N>
+struct matrix_transpose_per_index<G, I, N, N>
+{
+ static inline void apply(G &) {}
+};
+
+template <typename G, std::size_t I, std::size_t D, std::size_t N>
+struct matrix_transpose
+{
+ static inline void apply(G & g)
+ {
+ matrix_transpose_per_index<G, I, I+1, N>::apply(g);
+ matrix_transpose<G, I+1, D, N>::apply(g);
+ }
+};
+
+template <typename G, std::size_t D, std::size_t N>
+struct matrix_transpose<G, N, D, N>
+{
+ static inline void apply(G &) {}
+};
+
+}} // namespace detail::algebra
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_DETAIL_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/algorithms/reverse.hpp b/3party/boost/boost/geometry/extensions/algebra/algorithms/reverse.hpp
new file mode 100644
index 0000000000..6471c2ef0d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/algorithms/reverse.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_ALGORITHMS_REVERSE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_REVERSE_HPP
+
+#include <boost/geometry/algorithms/reverse.hpp>
+
+#include <boost/geometry/extensions/algebra/algorithms/detail.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// This is experimental implementation of reverse() which negates vectors
+// and inverses rotations. It doesn't work for them as for Geometries.
+
+template <typename Vector>
+struct reverse<Vector, vector_tag>
+{
+ static inline void apply(Vector & v)
+ {
+ detail::algebra::neg<0, dimension<Vector>::value>(v);
+ }
+};
+
+template <typename R>
+struct reverse<R, rotation_quaternion_tag>
+{
+ static inline void apply(R & r)
+ {
+ detail::algebra::neg<1, 4>(r);
+ }
+};
+
+template <typename R>
+struct reverse<R, rotation_matrix_tag>
+{
+ static inline void apply(R & r)
+ {
+ detail::algebra::matrix_transpose<
+ R, 0, 0, dimension<R>::value
+ >::apply(r);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_CLEAR_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/algorithms/rotation.hpp b/3party/boost/boost/geometry/extensions/algebra/algorithms/rotation.hpp
new file mode 100644
index 0000000000..2de45254ae
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/algorithms/rotation.hpp
@@ -0,0 +1,268 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_ALGORITHMS_ROTATION_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_ROTATION_HPP
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/extensions/algebra/algorithms/detail.hpp>
+
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
+
+// TODO - for multiplication of coordinates
+// if coordinate_type is_integral - use double as the result type
+
+namespace boost { namespace geometry {
+
+namespace detail { namespace rotation {
+
+template <typename V1, typename V2, typename Rotation, typename Tag1, typename Tag2, std::size_t Dimension>
+struct matrix
+{
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_DIMENSION, (Rotation));
+};
+
+template <typename V1, typename V2, typename Rotation>
+struct matrix<V1, V2, Rotation, vector_tag, vector_tag, 3>
+{
+ static const bool cs_check =
+ ::boost::is_same<typename traits::coordinate_system<V1>::type, cs::cartesian>::value &&
+ ::boost::is_same<typename traits::coordinate_system<V2>::type, cs::cartesian>::value;
+
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THOSE_SYSTEMS, (V1, V2));
+
+ typedef typename geometry::select_most_precise<
+ typename traits::coordinate_type<V1>::type,
+ typename traits::coordinate_type<V2>::type
+ >::type cv_type;
+
+ typedef typename geometry::select_most_precise<
+ cv_type,
+ typename traits::coordinate_type<Rotation>::type
+ >::type cr_type;
+
+ typedef model::vector<cv_type, 3> vector_type;
+
+ inline static void apply(V1 const& v1, V2 const& v2, Rotation & r)
+ {
+ namespace da = detail::algebra;
+
+ // TODO - should store coordinates in more precise variables before the normalization?
+
+ // angle
+ cv_type d = da::dot<0, 0, 3>(v1, v2);
+ cv_type l =
+ math::sqrt(da::dot<0, 0, 3>(v1, v1) * da::dot<0, 0, 3>(v2, v2));
+ cv_type c = d / l;
+
+ // rotation angle == 0
+ // not needed really, because in this case function still returns zero-rotation
+ if ( 1 - std::numeric_limits<cv_type>::epsilon() <= c )
+ {
+ set<0, 0>(r, 1); set<0, 1>(r, 0); set<0, 2>(r, 0);
+ set<1, 0>(r, 0); set<1, 1>(r, 1); set<1, 2>(r, 0);
+ set<2, 0>(r, 0); set<2, 1>(r, 0); set<2, 2>(r, 1);
+ return;
+ }
+
+ vector_type axis;
+
+ // rotation angle = 180
+ if ( c <= std::numeric_limits<cv_type>::epsilon() - 1 )
+ {
+ // find arbitrary rotation axis perpendicular to v1
+ da::cross<0, 0, 0>(vector_type(1, 0, 0), v1, axis);
+ if ( da::dot<0, 0, 3>(axis, axis) < std::numeric_limits<cr_type>::epsilon() )
+ da::cross<0, 0, 0>(vector_type(0, 1, 0), v1, axis);
+ }
+ else
+ {
+ // rotation axis
+ da::cross<0, 0, 0>(v1, v2, axis);
+ }
+
+ // sin
+ cv_type s = math::sqrt(1 - c * c);
+ cv_type t = 1 - c;
+ // normalize axis
+ da::normalize<0, 3>(axis);
+
+ cv_type txx = t*get<0>(axis)*get<0>(axis);
+ cv_type tyy = t*get<1>(axis)*get<1>(axis);
+ cv_type tzz = t*get<2>(axis)*get<2>(axis);
+ cv_type txy = t*get<0>(axis)*get<1>(axis);
+ cv_type sx = s*get<0>(axis);
+ cv_type txz = t*get<0>(axis)*get<2>(axis);
+ cv_type sy = s*get<1>(axis);
+ cv_type tyz = t*get<1>(axis)*get<2>(axis);
+ cv_type sz = s*get<2>(axis);
+
+ set<0, 0>(r, txx+c); set<0, 1>(r, txy-sz); set<0, 2>(r, txz+sy);
+ set<1, 0>(r, txy+sz); set<1, 1>(r, tyy+c); set<1, 2>(r, tyz-sx);
+ set<2, 0>(r, txz-sy); set<2, 1>(r, tyz+sx); set<2, 2>(r, tzz+c);
+ }
+};
+
+template <typename V1, typename V2, typename Rotation>
+struct matrix<V1, V2, Rotation, vector_tag, vector_tag, 2>
+{
+ static const bool cs_check =
+ ::boost::is_same<typename traits::coordinate_system<V1>::type, cs::cartesian>::value &&
+ ::boost::is_same<typename traits::coordinate_system<V2>::type, cs::cartesian>::value;
+
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THOSE_SYSTEMS, (V1, V2));
+
+ typedef typename geometry::select_most_precise<
+ typename traits::coordinate_type<V1>::type,
+ typename traits::coordinate_type<V2>::type
+ >::type cv_type;
+
+ inline static void apply(V1 const& v1, V2 const& v2, Rotation & r)
+ {
+ namespace da = detail::algebra;
+
+ // TODO - should store coordinates in more precise variables before the normalization?
+
+ // angle
+ cv_type d = da::dot<0, 0, 2>(v1, v2);
+ cv_type l =
+ math::sqrt(da::dot<0, 0, 2>(v1, v1) * da::dot<0, 0, 2>(v2, v2));
+ cv_type c = d / l;
+
+ // TODO return also if l == 0;
+
+ // rotation angle == 0
+ // not needed really, because in this case function still returns zero-rotation
+ if ( 1 - std::numeric_limits<cv_type>::epsilon() <= c )
+ {
+ set<0, 0>(r, 1); set<0, 1>(r, 0);
+ set<1, 0>(r, 0); set<1, 1>(r, 1);
+ }
+ // rotation angle = 180
+ else if ( c <= std::numeric_limits<cv_type>::epsilon() - 1 )
+ {
+ set<0, 0>(r, -1); set<0, 1>(r, 0);
+ set<1, 0>(r, 0); set<1, 1>(r, -1);
+ }
+ else
+ {
+ // sin
+ cv_type s = (get<0>(v1) * get<1>(v2) - get<1>(v1) * get<0>(v2)) / l;
+
+ set<0, 0>(r, c); set<0, 1>(r, -s);
+ set<1, 0>(r, s); set<1, 1>(r, c);
+ }
+ }
+};
+
+}} // namespace detail::rotation
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename V1, typename V2, typename Rotation,
+ typename Tag1 = typename tag<V1>::type,
+ typename Tag2 = typename tag<V2>::type,
+ typename RTag = typename tag<Rotation>::type
+>
+struct rotation
+{
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THOSE_TAGS, (Tag1, Tag2, Rotation));
+};
+
+template <typename V1, typename V2, typename Rotation>
+struct rotation<V1, V2, Rotation, vector_tag, vector_tag, rotation_quaternion_tag>
+{
+ static const bool cs_check =
+ ::boost::is_same<typename traits::coordinate_system<V1>::type, cs::cartesian>::value &&
+ ::boost::is_same<typename traits::coordinate_system<V2>::type, cs::cartesian>::value;
+
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THOSE_SYSTEMS, (V1, V2));
+
+ typedef typename geometry::select_most_precise<
+ typename traits::coordinate_type<V1>::type,
+ typename traits::coordinate_type<V2>::type
+ >::type cv_type;
+
+ typedef typename geometry::select_most_precise<
+ cv_type,
+ typename traits::coordinate_type<Rotation>::type
+ >::type cr_type;
+
+ typedef model::vector<cv_type, 3> vector_type;
+
+ inline static void apply(V1 const& v1, V2 const& v2, Rotation & r)
+ {
+ namespace da = detail::algebra;
+
+ // TODO - should store coordinates in more precise variables before the normalization?
+
+ cv_type d = da::dot<0, 0, 3>(v1, v2); // l1 * l2 * cos
+ cv_type l = math::sqrt(da::dot<0, 0, 3>(v1, v1) * da::dot<0, 0, 3>(v2, v2)); // l1 * l2
+ cv_type w = l + d; // l1 * l2 * ( 1 + cos )
+
+ // rotation angle == 0
+ // not needed really, because in this case function still returns zero-rotation
+ if ( 2*l-std::numeric_limits<cv_type>::epsilon() <= w )
+ {
+ set<0>(r, 1); set<0>(r, 0); set<0>(r, 0); set<0>(r, 0);
+ }
+ // rotation angle == pi
+ else if ( w <= std::numeric_limits<cv_type>::epsilon() )
+ {
+ set<0>(r, 0);
+ // find arbitrary rotation axis perpendicular to v1
+ da::cross<0, 0, 1>(vector_type(1, 0, 0), v1, r);
+ if ( da::dot<1, 1, 3>(r, r) < std::numeric_limits<cr_type>::epsilon() )
+ da::cross<0, 0, 1>(vector_type(0, 1, 0), v1, r);
+
+ // normalize axis
+ da::normalize<1, 3>(r);
+ }
+ else
+ {
+ set<0>(r, w); // l1 * l2 * ( 1 + cos )
+ // rotation axis
+ da::cross<0, 0, 1>(v1, v2, r); // l1 * l2 * sin * UNITA
+
+ // normalize quaternion
+ da::normalize<0, 4>(r);
+ }
+ }
+};
+
+template <typename V1, typename V2, typename Rotation>
+struct rotation<V1, V2, Rotation, vector_tag, vector_tag, rotation_matrix_tag>
+ : detail::rotation::matrix<V1, V2, Rotation, vector_tag, vector_tag, traits::dimension<Rotation>::value>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+template <typename V1, typename V2, typename Rotation>
+inline void rotation(V1 const& v1, V2 const& v2, Rotation & r)
+{
+ concept::check_concepts_and_equal_dimensions<V1 const, V2 const>();
+ // TODO - replace the following by check_equal_dimensions
+ concept::check_concepts_and_equal_dimensions<V1 const, Rotation>();
+
+ dispatch::rotation<V1, V2, Rotation>::apply(v1, v2, r);
+}
+
+template <typename Rotation, typename V1, typename V2>
+inline Rotation return_rotation(V1 const& v1, V2 const& v2)
+{
+ Rotation r;
+ translation(v1, v2, r);
+ return r;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_ROTATION_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/algorithms/transform_geometrically.hpp b/3party/boost/boost/geometry/extensions/algebra/algorithms/transform_geometrically.hpp
new file mode 100644
index 0000000000..501cdde798
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/algorithms/transform_geometrically.hpp
@@ -0,0 +1,173 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_ALGORITHMS_TRANSFORM_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSFORM_HPP
+
+#include <boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+
+namespace boost { namespace geometry {
+
+namespace detail { namespace transform_geometrically {
+
+template <typename Box, typename Vector, std::size_t Dimension>
+struct box_vector_cartesian
+{
+ BOOST_MPL_ASSERT_MSG((0 < Dimension), INVALID_DIMENSION, (Box));
+
+ static inline void apply(Box & box, Vector const& vector)
+ {
+ box_vector_cartesian<Box, Vector, Dimension-1>::apply(box, vector);
+ set<min_corner, Dimension-1>(box, get<min_corner, Dimension-1>(box) + get<Dimension-1>(vector));
+ set<max_corner, Dimension-1>(box, get<max_corner, Dimension-1>(box) + get<Dimension-1>(vector));
+ }
+};
+
+template <typename Box, typename Vector>
+struct box_vector_cartesian<Box, Vector, 1>
+{
+ static inline void apply(Box & box, Vector const& vector)
+ {
+ set<min_corner, 0>(box, get<min_corner, 0>(box) + get<0>(vector));
+ set<max_corner, 0>(box, get<max_corner, 0>(box) + get<0>(vector));
+ }
+};
+
+}} // namespace detail::transform
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Geometry, typename Transform,
+ typename GTag = typename tag<Geometry>::type,
+ typename TTag = typename tag<Transform>::type>
+struct transform_geometrically
+{
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THOSE_TAGS, (GTag, TTag));
+};
+
+// Point translation by Vector
+template <typename Point, typename Vector>
+struct transform_geometrically<Point, Vector, point_tag, vector_tag>
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+ BOOST_CONCEPT_ASSERT( (concept::Vector<Vector>) );
+
+ static inline void apply(Point & point, Vector const& vector)
+ {
+ typedef boost::mpl::bool_<
+ boost::is_same<
+ typename traits::coordinate_system<Point>::type,
+ cs::cartesian
+ >::value
+ > is_cartesian;
+ apply(point, vector, is_cartesian());
+ }
+
+ static inline void apply(Point & point, Vector const& vector, boost::mpl::bool_<true> /*is_cartesian*/)
+ {
+ for_each_coordinate(point, detail::point_operation<Vector, std::plus>(vector));
+ }
+
+ static inline void apply(Point & point, Vector const& vector, boost::mpl::bool_<false> /*is_cartesian*/)
+ {
+ typedef typename traits::coordinate_system<Point>::type cs;
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_CS, (cs));
+ }
+};
+
+// Box translation by Vector
+template <typename Box, typename Vector>
+struct transform_geometrically<Box, Vector, box_tag, vector_tag>
+{
+ typedef typename traits::point_type<Box>::type point_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+ BOOST_CONCEPT_ASSERT( (concept::Vector<Vector>) );
+
+ static inline void apply(Box & box, Vector const& vector)
+ {
+ typedef boost::mpl::bool_<
+ boost::is_same<
+ typename traits::coordinate_system<point_type>::type,
+ cs::cartesian
+ >::value
+ > is_cartesian;
+ apply(box, vector, is_cartesian());
+ }
+
+ static inline void apply(Box & box, Vector const& vector, boost::mpl::bool_<true> /*is_cartesian*/)
+ {
+ geometry::detail::transform_geometrically::box_vector_cartesian<
+ Box, Vector, traits::dimension<point_type>::value
+ >::apply(box, vector);
+ }
+
+ static inline void apply(Box & box, Vector const& vector, boost::mpl::bool_<false> /*is_cartesian*/)
+ {
+ typedef typename traits::coordinate_system<point_type>::type cs;
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_CS, (cs));
+ }
+};
+
+// Vector rotation by Quaternion
+template <typename Vector, typename RotationQuaternion>
+struct transform_geometrically<Vector, RotationQuaternion, vector_tag, rotation_quaternion_tag>
+{
+ static inline void apply(Vector & v, RotationQuaternion const& r)
+ {
+ concept::check_concepts_and_equal_dimensions<Vector, RotationQuaternion const>();
+
+ detail::algebra::quaternion_rotate(v, r);
+ }
+};
+
+// Vector rotation by Matrix
+template <typename Vector, typename RotationMatrix>
+struct transform_geometrically<Vector, RotationMatrix, vector_tag, rotation_matrix_tag>
+{
+ static inline void apply(Vector & v, RotationMatrix const& r)
+ {
+ concept::check_concepts_and_equal_dimensions<Vector, RotationMatrix const>();
+
+ // TODO vector_type and convert from Vector
+ Vector tmp(v);
+ detail::algebra::matrix_rotate(r, tmp, v);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+template <typename Geometry, typename Transformation>
+inline void transform_geometrically(Geometry & g, Transformation const& t)
+{
+ dispatch::transform_geometrically<Geometry, Transformation>::apply(g, t);
+}
+
+template <typename GeometrySrc, typename Transformation, typename GeometryDst>
+inline void transformed_geometrically(GeometrySrc const& gsrc, Transformation const& t, GeometryDst & gdst)
+{
+ geometry::convert(gsrc, gdst);
+ geometry::transform_geometrically(gdst, t);
+}
+
+template <typename GeometryDst, typename GeometrySrc, typename Transformation>
+inline GeometryDst return_transformed_geometrically(GeometrySrc const& gsrc, Transformation const& t)
+{
+ GeometryDst res;
+ transformed_geometrically(gsrc, t, res);
+ return res;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSFORM_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/algorithms/translation.hpp b/3party/boost/boost/geometry/extensions/algebra/algorithms/translation.hpp
new file mode 100644
index 0000000000..feeb3a70c2
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/algorithms/translation.hpp
@@ -0,0 +1,44 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_ALGORITHMS_TRANSLATION_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSLATION_HPP
+
+#include <boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp>
+
+//#include <boost/geometry/geometries/concepts/point_concept.hpp>
+//#include <boost/geometry/util/for_each_coordinate.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+
+namespace boost { namespace geometry
+{
+
+// TODO - implement point_operation2 taking two arguments
+
+template <typename Point1, typename Point2, typename Vector>
+inline void translation(Point1 const& p1, Point2 const& p2, Vector & v)
+{
+ concept::check_concepts_and_equal_dimensions<Point1 const, Point2 const>();
+ // TODO - replace the following by check_equal_dimensions
+ concept::check_concepts_and_equal_dimensions<Point1 const, Vector>();
+
+ for_each_coordinate(v, detail::point_assignment<Point2>(p2));
+ for_each_coordinate(v, detail::point_operation<Point1, std::minus>(p1));
+}
+
+template <typename Vector, typename Point1, typename Point2>
+inline Vector return_translation(Point1 const& p1, Point2 const& p2)
+{
+ Vector v;
+ translation(p1, p2, v);
+ return v;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_ASSIGN_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/core/access.hpp b/3party/boost/boost/geometry/extensions/algebra/core/access.hpp
new file mode 100644
index 0000000000..49bc79e690
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/core/access.hpp
@@ -0,0 +1,137 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_CORE_ACCESS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_CORE_ACCESS_HPP
+
+
+
+#include <boost/geometry/core/access.hpp>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Vector, typename CoordinateType, std::size_t Dimension>
+struct access<vector_tag, Vector, CoordinateType, Dimension, boost::false_type>
+{
+ static inline CoordinateType get(Vector const& v)
+ {
+ return traits::access<Vector, Dimension>::get(v);
+ }
+ static inline void set(Vector& v, CoordinateType const& value)
+ {
+ traits::access<Vector, Dimension>::set(v, value);
+ }
+};
+
+template <typename Vector, typename CoordinateType, std::size_t Dimension>
+struct access<vector_tag, Vector, CoordinateType, Dimension, boost::true_type>
+{
+ static inline CoordinateType get(Vector const* v)
+ {
+ return traits::access<typename boost::remove_pointer<Vector>::type, Dimension>::get(*v);
+ }
+ static inline void set(Vector* v, CoordinateType const& value)
+ {
+ traits::access<typename boost::remove_pointer<Vector>::type, Dimension>::set(*v, value);
+ }
+};
+
+template <typename Q, typename CoordinateType, std::size_t Dimension>
+struct access<quaternion_tag, Q, CoordinateType, Dimension, boost::false_type>
+{
+ static inline CoordinateType get(Q const& v)
+ {
+ return traits::access<Q, Dimension>::get(v);
+ }
+ static inline void set(Q& v, CoordinateType const& value)
+ {
+ traits::access<Q, Dimension>::set(v, value);
+ }
+};
+
+template <typename Q, typename CoordinateType, std::size_t Dimension>
+struct access<quaternion_tag, Q, CoordinateType, Dimension, boost::true_type>
+{
+ static inline CoordinateType get(Q const* v)
+ {
+ return traits::access<typename boost::remove_pointer<Q>::type, Dimension>::get(*v);
+ }
+ static inline void set(Q* v, CoordinateType const& value)
+ {
+ traits::access<typename boost::remove_pointer<Q>::type, Dimension>::set(*v, value);
+ }
+};
+
+template<typename M, typename CoordinateType, std::size_t I, std::size_t J>
+struct indexed_access<matrix_tag, M, CoordinateType, I, J, boost::false_type>
+ : detail::indexed_access_non_pointer<M, CoordinateType, I, J>
+{};
+
+template<typename M, typename CoordinateType, std::size_t I, std::size_t J>
+struct indexed_access<matrix_tag, M, CoordinateType, I, J, boost::true_type>
+ : detail::indexed_access_pointer<M, CoordinateType, I, J>
+{};
+
+
+template <typename Q, typename CoordinateType, std::size_t Dimension>
+struct access<rotation_quaternion_tag, Q, CoordinateType, Dimension, boost::false_type>
+{
+ static inline CoordinateType get(Q const& v)
+ {
+ return traits::access<Q, Dimension>::get(v);
+ }
+ static inline void set(Q& v, CoordinateType const& value)
+ {
+ traits::access<Q, Dimension>::set(v, value);
+ }
+};
+
+template <typename Q, typename CoordinateType, std::size_t Dimension>
+struct access<rotation_quaternion_tag, Q, CoordinateType, Dimension, boost::true_type>
+{
+ static inline CoordinateType get(Q const* v)
+ {
+ return traits::access<typename boost::remove_pointer<Q>::type, Dimension>::get(*v);
+ }
+ static inline void set(Q* v, CoordinateType const& value)
+ {
+ traits::access<typename boost::remove_pointer<Q>::type, Dimension>::set(*v, value);
+ }
+};
+
+template<typename RM, typename CoordinateType, std::size_t I, std::size_t J>
+struct indexed_access<rotation_matrix_tag, RM, CoordinateType, I, J, boost::false_type>
+ : detail::indexed_access_non_pointer<RM, CoordinateType, I, J>
+{};
+
+template<typename RM, typename CoordinateType, std::size_t I, std::size_t J>
+struct indexed_access<rotation_matrix_tag, RM, CoordinateType, I, J, boost::true_type>
+ : detail::indexed_access_pointer<RM, CoordinateType, I, J>
+{};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_CORE_ACCESS_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/core/coordinate_dimension.hpp b/3party/boost/boost/geometry/extensions/algebra/core/coordinate_dimension.hpp
new file mode 100644
index 0000000000..ff1f3c96e6
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/core/coordinate_dimension.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_CORE_COORDINATE_DIMENSION_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_CORE_COORDINATE_DIMENSION_HPP
+
+#include <boost/geometry/core/coordinate_system.hpp>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+
+namespace boost { namespace geometry {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch {
+
+template <typename V>
+struct dimension<vector_tag, V>
+ : traits::dimension<typename geometry::util::bare_type<V>::type>
+{};
+
+template <typename G>
+struct dimension<quaternion_tag, G>
+ : traits::dimension<typename geometry::util::bare_type<G>::type>
+{};
+
+template <typename G, std::size_t Index>
+struct indexed_dimension<matrix_tag, G, Index>
+ : traits::indexed_dimension<typename geometry::util::bare_type<G>::type, Index>
+{};
+
+
+template <typename G>
+struct dimension<rotation_quaternion_tag, G>
+ : traits::dimension<typename geometry::util::bare_type<G>::type>
+{};
+
+template <typename G>
+struct dimension<rotation_matrix_tag, G>
+ : traits::dimension<typename geometry::util::bare_type<G>::type>
+{};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_CORE_COORDINATE_DIMENSION_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/core/coordinate_system.hpp b/3party/boost/boost/geometry/extensions/algebra/core/coordinate_system.hpp
new file mode 100644
index 0000000000..67c206e895
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/core/coordinate_system.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_CORE_COORDINATE_SYSTEM_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_CORE_COORDINATE_SYSTEM_HPP
+
+#include <boost/geometry/core/coordinate_system.hpp>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+
+namespace boost { namespace geometry {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch {
+
+template <typename Vector>
+struct coordinate_system<vector_tag, Vector>
+{
+ typedef typename traits::coordinate_system<
+ typename geometry::util::bare_type<Vector>::type
+ >::type type;
+};
+
+//template <typename G>
+//struct coordinate_system<quaternion_tag, G>
+//{
+// typedef typename traits::coordinate_system<
+// typename geometry::util::bare_type<G>::type
+// >::type type;
+//};
+//
+//template <typename G>
+//struct coordinate_system<matrix_tag, G>
+//{
+// typedef typename traits::coordinate_system<
+// typename geometry::util::bare_type<G>::type
+// >::type type;
+//};
+
+
+template <typename G>
+struct coordinate_system<rotation_quaternion_tag, G>
+{
+ typedef typename traits::coordinate_system<
+ typename geometry::util::bare_type<G>::type
+ >::type type;
+};
+
+template <typename G>
+struct coordinate_system<rotation_matrix_tag, G>
+{
+ typedef typename traits::coordinate_system<
+ typename geometry::util::bare_type<G>::type
+ >::type type;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_CORE_COORDINATE_SYSTEM_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/core/coordinate_type.hpp b/3party/boost/boost/geometry/extensions/algebra/core/coordinate_type.hpp
new file mode 100644
index 0000000000..d164455818
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/core/coordinate_type.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_CORE_COORDINATE_TYPE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_CORE_COORDINATE_TYPE_HPP
+
+#include <boost/geometry/core/coordinate_type.hpp>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+
+namespace boost { namespace geometry {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch {
+
+template <typename Vector>
+struct coordinate_type<vector_tag, Vector>
+{
+ typedef typename traits::coordinate_type<
+ typename geometry::util::bare_type<Vector>::type
+ >::type type;
+};
+
+template <typename G>
+struct coordinate_type<quaternion_tag, G>
+{
+ typedef typename traits::coordinate_type<
+ typename geometry::util::bare_type<G>::type
+ >::type type;
+};
+
+template <typename G>
+struct coordinate_type<matrix_tag, G>
+{
+ typedef typename traits::coordinate_type<
+ typename geometry::util::bare_type<G>::type
+ >::type type;
+};
+
+
+template <typename G>
+struct coordinate_type<rotation_quaternion_tag, G>
+{
+ typedef typename traits::coordinate_type<
+ typename geometry::util::bare_type<G>::type
+ >::type type;
+};
+
+template <typename G>
+struct coordinate_type<rotation_matrix_tag, G>
+{
+ typedef typename traits::coordinate_type<
+ typename geometry::util::bare_type<G>::type
+ >::type type;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_CORE_COORDINATE_TYPE_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/core/tags.hpp b/3party/boost/boost/geometry/extensions/algebra/core/tags.hpp
new file mode 100644
index 0000000000..908ac1ced6
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/core/tags.hpp
@@ -0,0 +1,33 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_CORE_TAGS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_CORE_TAGS_HPP
+
+
+namespace boost { namespace geometry
+{
+
+
+struct vector_tag {};
+struct quaternion_tag {};
+struct matrix_tag {};
+
+struct rotation_quaternion_tag {};
+struct rotation_matrix_tag {};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_CORE_TAGS_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/check.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/check.hpp
new file mode 100644
index 0000000000..606095f111
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/check.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_CONCEPTS_CHECK_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_CHECK_HPP
+
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Geometry>
+struct check<Geometry, vector_tag, true>
+ : detail::concept_check::check<concept::ConstVector<Geometry> >
+{};
+
+template <typename Geometry>
+struct check<Geometry, vector_tag, false>
+ : detail::concept_check::check<concept::Vector<Geometry> >
+{};
+
+template <typename Geometry>
+struct check<Geometry, rotation_quaternion_tag, true>
+ : detail::concept_check::check<concept::ConstRotationQuaternion<Geometry> >
+{};
+
+template <typename Geometry>
+struct check<Geometry, rotation_quaternion_tag, false>
+ : detail::concept_check::check<concept::RotationQuaternion<Geometry> >
+{};
+
+template <typename Geometry>
+struct check<Geometry, rotation_matrix_tag, true>
+ : detail::concept_check::check<concept::ConstRotationMatrix<Geometry> >
+{};
+
+template <typename Geometry>
+struct check<Geometry, rotation_matrix_tag, false>
+ : detail::concept_check::check<concept::RotationMatrix<Geometry> >
+{};
+
+} // namespace dispatch
+#endif
+
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_CHECK_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/matrix_concept.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/matrix_concept.hpp
new file mode 100644
index 0000000000..0bb880a7ef
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/matrix_concept.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_CONCEPTS_MATRIX_CONCEPT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_MATRIX_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/access.hpp>
+
+namespace boost { namespace geometry { namespace concept {
+
+template <typename Geometry>
+class Matrix
+{
+#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 G, std::size_t I, std::size_t J, std::size_t N>
+ struct dimension_checker_row
+ {
+ static void apply()
+ {
+ G* g = 0;
+ geometry::set<I, J>(*g, geometry::get<I, J>(*g));
+ dimension_checker_row<G, I, J+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker_row<G, I, N, N>
+ {
+ static void apply() {}
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ dimension_checker_row<G, I, 0, N>;
+ dimension_checker<G, I+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t N>
+ struct dimension_checker<G, N, N>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the concept
+ BOOST_CONCEPT_USAGE(Matrix)
+ {
+ static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, ccount>::apply();
+ }
+#endif
+};
+
+
+template <typename Geometry>
+class ConstMatrix
+{
+#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 G, std::size_t I, std::size_t J, std::size_t N>
+ struct dimension_checker_row
+ {
+ static void apply()
+ {
+ const G* g = 0;
+ ctype coord(geometry::get<I, J>(*g));
+ boost::ignore_unused_variable_warning(coord);
+ dimension_checker_row<G, I, J+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker_row<G, I, N, N>
+ {
+ static void apply() {}
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ dimension_checker_row<G, I, 0, N>;
+ dimension_checker<G, I+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t N>
+ struct dimension_checker<G, N, N>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the concept
+ BOOST_CONCEPT_USAGE(ConstMatrix)
+ {
+ //static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ //BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ //dimension_checker<Geometry, 0, ccount>::apply();
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_MATRIX_CONCEPT_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/quaternion_concept.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/quaternion_concept.hpp
new file mode 100644
index 0000000000..376d838005
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/quaternion_concept.hpp
@@ -0,0 +1,111 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_CONCEPTS_QUATERNION_CONCEPT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_QUATERNION_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/access.hpp>
+
+namespace boost { namespace geometry { namespace concept {
+
+template <typename Geometry>
+class Quaternion
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ //typedef typename coordinate_type<Geometry>::type ctype;
+ //typedef typename coordinate_system<Geometry>::type csystem;
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ G* g = 0;
+ geometry::set<I>(*g, geometry::get<I>(*g));
+ dimension_checker<G, I+1, N>::apply();
+ }
+ };
+
+
+ template <typename G, std::size_t N>
+ struct dimension_checker<G, N, N>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the Vector concept
+ BOOST_CONCEPT_USAGE(Quaternion)
+ {
+ //static const bool dim_check = dimension<Geometry>::value == 4;
+ //BOOST_MPL_ASSERT_MSG(dim_check, INVALID_DIMENSION, (RotationQuaternion));
+ //static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ //BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, 4>::apply();
+ }
+#endif
+};
+
+
+template <typename Geometry>
+class ConstQuaternion
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ //typedef typename coordinate_type<Geometry>::type ctype;
+ //typedef typename coordinate_system<Geometry>::type csystem;
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ const G* g = 0;
+ ctype coord(geometry::get<I>(*g));
+ boost::ignore_unused_variable_warning(coord);
+ dimension_checker<G, I+1, N>::apply();
+ }
+ };
+
+
+ template <typename G, std::size_t N>
+ struct dimension_checker<G, N, N>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the ConstVector concept
+ BOOST_CONCEPT_USAGE(ConstQuaternion)
+ {
+ //static const bool dim_check = dimension<Geometry>::value == 4;
+ //BOOST_MPL_ASSERT_MSG(dim_check, INVALID_DIMENSION, (ConstRotationQuaternion));
+ //static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ //BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, 4>::apply();
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_QUATERNION_CONCEPT_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp
new file mode 100644
index 0000000000..8f54f3dd61
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_CONCEPTS_ROTATION_MATRIX_CONCEPT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_ROTATION_MATRIX_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/access.hpp>
+
+namespace boost { namespace geometry { namespace concept {
+
+template <typename Geometry>
+class RotationMatrix
+{
+#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 G, std::size_t I, std::size_t J, std::size_t N>
+ struct dimension_checker_row
+ {
+ static void apply()
+ {
+ G* g = 0;
+ geometry::set<I, J>(*g, geometry::get<I, J>(*g));
+ dimension_checker_row<G, I, J+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker_row<G, I, N, N>
+ {
+ static void apply() {}
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ dimension_checker_row<G, I, 0, N>;
+ dimension_checker<G, I+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t N>
+ struct dimension_checker<G, N, N>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the concept
+ BOOST_CONCEPT_USAGE(RotationMatrix)
+ {
+ static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, ccount>::apply();
+ }
+#endif
+};
+
+
+template <typename Geometry>
+class ConstRotationMatrix
+{
+#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 G, std::size_t I, std::size_t J, std::size_t N>
+ struct dimension_checker_row
+ {
+ static void apply()
+ {
+ const G* g = 0;
+ ctype coord(geometry::get<I, J>(*g));
+ boost::ignore_unused_variable_warning(coord);
+ dimension_checker_row<G, I, J+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker_row<G, I, N, N>
+ {
+ static void apply() {}
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ dimension_checker_row<G, I, 0, N>;
+ dimension_checker<G, I+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t N>
+ struct dimension_checker<G, N, N>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the concept
+ BOOST_CONCEPT_USAGE(ConstRotationMatrix)
+ {
+ static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, ccount>::apply();
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_ROTATION_MATRIX_CONCEPT_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp
new file mode 100644
index 0000000000..cd0c0661bb
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp
@@ -0,0 +1,111 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_CONCEPTS_ROTATION_QUATERNION_CONCEPT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_ROTATION_QUATERNION_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/access.hpp>
+
+namespace boost { namespace geometry { namespace concept {
+
+template <typename Geometry>
+class RotationQuaternion
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ typedef typename coordinate_type<Geometry>::type ctype;
+ typedef typename coordinate_system<Geometry>::type csystem;
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ G* g = 0;
+ geometry::set<I>(*g, geometry::get<I>(*g));
+ dimension_checker<G, I+1, N>::apply();
+ }
+ };
+
+
+ template <typename G, std::size_t N>
+ struct dimension_checker<G, N, N>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the Vector concept
+ BOOST_CONCEPT_USAGE(RotationQuaternion)
+ {
+ static const bool dim_check = dimension<Geometry>::value == 3;
+ BOOST_MPL_ASSERT_MSG(dim_check, INVALID_DIMENSION, (RotationQuaternion));
+ static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, 4>::apply();
+ }
+#endif
+};
+
+
+template <typename Geometry>
+class ConstRotationQuaternion
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ typedef typename coordinate_type<Geometry>::type ctype;
+ typedef typename coordinate_system<Geometry>::type csystem;
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ const G* g = 0;
+ ctype coord(geometry::get<I>(*g));
+ boost::ignore_unused_variable_warning(coord);
+ dimension_checker<G, I+1, N>::apply();
+ }
+ };
+
+
+ template <typename G, std::size_t N>
+ struct dimension_checker<G, N, N>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the ConstVector concept
+ BOOST_CONCEPT_USAGE(ConstRotationQuaternion)
+ {
+ static const bool dim_check = dimension<Geometry>::value == 3;
+ BOOST_MPL_ASSERT_MSG(dim_check, INVALID_DIMENSION, (ConstRotationQuaternion));
+ static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, 4>::apply();
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_ROTATION_QUATERNION_CONCEPT_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp
new file mode 100644
index 0000000000..b13753a491
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp
@@ -0,0 +1,112 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_CONCEPTS_VECTOR_CONCEPT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_VECTOR_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/access.hpp>
+
+namespace boost { namespace geometry { namespace concept {
+
+template <typename Geometry>
+class Vector
+{
+#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 V, std::size_t Dimension, std::size_t DimensionCount>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ V* v = 0;
+ geometry::set<Dimension>(*v, geometry::get<Dimension>(*v));
+ dimension_checker<V, Dimension+1, DimensionCount>::apply();
+ }
+ };
+
+
+ template <typename V, std::size_t DimensionCount>
+ struct dimension_checker<V, DimensionCount, DimensionCount>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the Vector concept
+ BOOST_CONCEPT_USAGE(Vector)
+ {
+ static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, ccount>::apply();
+ }
+#endif
+};
+
+
+template <typename Geometry>
+class ConstVector
+{
+#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 V, std::size_t Dimension, std::size_t DimensionCount>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ const V* v = 0;
+ ctype coord(geometry::get<Dimension>(*v));
+ boost::ignore_unused_variable_warning(coord);
+ dimension_checker<V, Dimension+1, DimensionCount>::apply();
+ }
+ };
+
+
+ template <typename V, std::size_t DimensionCount>
+ struct dimension_checker<V, DimensionCount, DimensionCount>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the ConstVector concept
+ BOOST_CONCEPT_USAGE(ConstVector)
+ {
+ static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, ccount>::apply();
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_VECTOR_CONCEPT_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/matrix.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/matrix.hpp
new file mode 100644
index 0000000000..61b988403d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/matrix.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_MATRIX_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_MATRIX_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/matrix_concept.hpp>
+
+namespace boost { namespace geometry {
+
+namespace model {
+
+template <typename T, std::size_t Rows, std::size_t Cols>
+class matrix
+{
+ BOOST_CONCEPT_ASSERT( (concept::Matrix<matrix>) );
+
+public:
+
+ /// @brief Default constructor, no initialization
+ inline matrix()
+ {}
+
+ /// @brief Get a coordinate
+ /// @tparam I row index
+ /// @tparam J col index
+ /// @return the cell value
+ template <std::size_t I, std::size_t J>
+ inline T const& get() const
+ {
+ BOOST_STATIC_ASSERT(I < Rows);
+ BOOST_STATIC_ASSERT(J < Cols);
+ return m_values[I + Rows * J];
+ }
+
+ /// @brief Set a coordinate
+ /// @tparam I row index
+ /// @tparam J col index
+ /// @param value value to set
+ template <std::size_t I, std::size_t J>
+ inline void set(T const& value)
+ {
+ BOOST_STATIC_ASSERT(I < Rows);
+ BOOST_STATIC_ASSERT(J < Cols);
+ m_values[I + Rows * J] = value;
+ }
+
+private:
+
+ T m_values[Rows * Cols];
+};
+
+} // namespace model
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename CoordinateType, std::size_t Rows, std::size_t Cols>
+struct tag<model::matrix<CoordinateType, Rows, Cols> >
+{
+ typedef matrix_tag type;
+};
+
+template <typename CoordinateType, std::size_t Rows, std::size_t Cols>
+struct coordinate_type<model::matrix<CoordinateType, Rows, Cols> >
+{
+ typedef CoordinateType type;
+};
+
+//template <typename CoordinateType, std::size_t Rows, std::size_t Cols>
+//struct coordinate_system<model::matrix<CoordinateType, Rows, Cols> >
+//{
+// typedef cs::cartesian type;
+//};
+
+// TODO - move this class to traits.hpp
+template <typename Geometry, std::size_t Index>
+struct indexed_dimension
+{
+ BOOST_MPL_ASSERT_MSG(false,
+ NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_OR_INDEX,
+ (Geometry, boost::integral_constant<std::size_t, Index>));
+};
+
+template <typename CoordinateType, std::size_t Rows, std::size_t Cols>
+struct indexed_dimension<model::matrix<CoordinateType, Rows, Cols>, 0>
+ : boost::integral_constant<std::size_t, Rows>
+{};
+
+template <typename CoordinateType, std::size_t Rows, std::size_t Cols>
+struct indexed_dimension<model::matrix<CoordinateType, Rows, Cols>, 1>
+ : boost::integral_constant<std::size_t, Cols>
+{};
+
+template <typename CoordinateType, std::size_t Rows, std::size_t Cols, std::size_t I, std::size_t J>
+struct indexed_access<model::matrix<CoordinateType, Dimension>, I, J>
+{
+ typedef CoordinateType coordinate_type;
+
+ static inline coordinate_type get(model::matrix<CoordinateType, Rows, Cols> const& m)
+ {
+ return m.template get<I, J>();
+ }
+
+ static inline void set(model::matrix<CoordinateType, Rows, Cols> & m, coordinate_type const& value)
+ {
+ m.template set<I, J>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_MATRIX_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/quaternion.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/quaternion.hpp
new file mode 100644
index 0000000000..f252285bdd
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/quaternion.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_QUATERNION_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_QUATERNION_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/quaternion_concept.hpp>
+
+// WARNING!
+// It is probable that the sequence of coordinate will change in the future
+// at the beginning there would be xyz, w would become the last coordinate
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+template <typename T>
+class quaternion
+{
+ BOOST_CONCEPT_ASSERT( (concept::Quaternion<quaternion>) );
+
+public:
+
+ /// @brief Default constructor, no initialization
+ inline quaternion()
+ {}
+
+ /// @brief Constructor to set components
+ inline quaternion(T const& w, T const& x, T const& y, T const& z)
+ {
+ m_values[0] = w;
+ m_values[1] = x;
+ m_values[2] = y;
+ m_values[3] = z;
+ }
+
+ /// @brief Get a coordinate
+ /// @tparam K coordinate to get
+ /// @return the coordinate
+ template <std::size_t K>
+ inline T const& get() const
+ {
+ BOOST_STATIC_ASSERT(K < 4);
+ 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(T const& value)
+ {
+ BOOST_STATIC_ASSERT(K < 4);
+ m_values[K] = value;
+ }
+
+private:
+
+ T m_values[4];
+};
+
+
+} // namespace model
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename CoordinateType>
+struct tag<model::quaternion<CoordinateType> >
+{
+ typedef quaternion_tag type;
+};
+
+template <typename CoordinateType>
+struct coordinate_type<model::quaternion<CoordinateType> >
+{
+ typedef CoordinateType type;
+};
+
+//template <typename CoordinateType>
+//struct coordinate_system<model::quaternion<CoordinateType> >
+//{
+// typedef cs::cartesian type;
+//};
+
+template <typename CoordinateType>
+struct dimension<model::quaternion<CoordinateType> >
+ : boost::integral_constant<std::size_t, 4>
+{};
+
+template<typename CoordinateType, std::size_t Dimension>
+struct access<model::quaternion<CoordinateType>, Dimension>
+{
+ static inline CoordinateType get(
+ model::quaternion<CoordinateType> const& v)
+ {
+ return v.template get<Dimension>();
+ }
+
+ static inline void set(
+ model::quaternion<CoordinateType> & v,
+ CoordinateType const& value)
+ {
+ v.template set<Dimension>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_QUATERNION_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/rotation_matrix.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/rotation_matrix.hpp
new file mode 100644
index 0000000000..2a4d30ed86
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/rotation_matrix.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_ROTATION_MATRIX_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_ROTATION_MATRIX_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp>
+
+namespace boost { namespace geometry {
+
+namespace model {
+
+template <typename T, std::size_t Dimension>
+class rotation_matrix
+{
+ BOOST_CONCEPT_ASSERT( (concept::RotationMatrix<rotation_matrix>) );
+
+public:
+
+ /// @brief Default constructor, no initialization
+ inline rotation_matrix()
+ {}
+
+ /// @brief Get a coordinate
+ /// @tparam I row index
+ /// @tparam J col index
+ /// @return the cell value
+ template <std::size_t I, std::size_t J>
+ inline T const& get() const
+ {
+ BOOST_STATIC_ASSERT(I < Dimension);
+ BOOST_STATIC_ASSERT(J < Dimension);
+ return m_values[I * Dimension + J];
+ }
+
+ /// @brief Set a coordinate
+ /// @tparam I row index
+ /// @tparam J col index
+ /// @param value value to set
+ template <std::size_t I, std::size_t J>
+ inline void set(T const& value)
+ {
+ BOOST_STATIC_ASSERT(I < Dimension);
+ BOOST_STATIC_ASSERT(J < Dimension);
+ m_values[I * Dimension + J] = value;
+ }
+
+private:
+
+ T m_values[Dimension * Dimension];
+};
+
+} // namespace model
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename CoordinateType, std::size_t Dimension>
+struct tag<model::rotation_matrix<CoordinateType, Dimension> >
+{
+ typedef rotation_matrix_tag type;
+};
+
+template <typename CoordinateType, std::size_t Dimension>
+struct coordinate_type<model::rotation_matrix<CoordinateType, Dimension> >
+{
+ typedef CoordinateType type;
+};
+
+template <typename CoordinateType, std::size_t Dimension>
+struct coordinate_system<model::rotation_matrix<CoordinateType, Dimension> >
+{
+ typedef cs::cartesian type;
+};
+
+template <typename CoordinateType, std::size_t Dimension>
+struct dimension<model::rotation_matrix<CoordinateType, Dimension> >
+ : boost::mpl::int_<Dimension>
+{};
+
+template <typename CoordinateType, std::size_t Dimension, std::size_t I, std::size_t J>
+struct indexed_access<model::rotation_matrix<CoordinateType, Dimension>, I, J>
+{
+ typedef CoordinateType coordinate_type;
+
+ static inline coordinate_type get(model::rotation_matrix<CoordinateType, Dimension> const& m)
+ {
+ return m.template get<I, J>();
+ }
+
+ static inline void set(model::rotation_matrix<CoordinateType, Dimension> & m, coordinate_type const& value)
+ {
+ m.template set<I, J>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_ROTATION_MATRIX_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/rotation_quaternion.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/rotation_quaternion.hpp
new file mode 100644
index 0000000000..ebc99ffb62
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/rotation_quaternion.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_ROTATION_QUATERNION_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_ROTATION_QUATERNION_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
+
+// WARNING!
+// It is probable that the sequence of coordinate will change in the future
+// at the beginning there would be xyz, w would become the last coordinate
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+template <typename T>
+class rotation_quaternion
+{
+ BOOST_CONCEPT_ASSERT( (concept::RotationQuaternion<rotation_quaternion>) );
+
+public:
+
+ /// @brief Default constructor, no initialization
+ inline rotation_quaternion()
+ {}
+
+ /// @brief Constructor to set components
+ inline rotation_quaternion(T const& w, T const& x, T const& y, T const& z)
+ {
+ m_values[0] = w;
+ m_values[1] = x;
+ m_values[2] = y;
+ m_values[3] = z;
+ }
+
+ /// @brief Get a coordinate
+ /// @tparam K coordinate to get
+ /// @return the coordinate
+ template <std::size_t K>
+ inline T const& get() const
+ {
+ BOOST_STATIC_ASSERT(K < 4);
+ 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(T const& value)
+ {
+ BOOST_STATIC_ASSERT(K < 4);
+ m_values[K] = value;
+ }
+
+private:
+
+ T m_values[4];
+};
+
+
+} // namespace model
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename CoordinateType>
+struct tag<model::rotation_quaternion<CoordinateType> >
+{
+ typedef rotation_quaternion_tag type;
+};
+
+template <typename CoordinateType>
+struct coordinate_type<model::rotation_quaternion<CoordinateType> >
+{
+ typedef CoordinateType type;
+};
+
+template <typename CoordinateType>
+struct coordinate_system<model::rotation_quaternion<CoordinateType> >
+{
+ typedef cs::cartesian type;
+};
+
+template <typename CoordinateType>
+struct dimension<model::rotation_quaternion<CoordinateType> >
+ : boost::mpl::int_<3>
+{};
+
+template
+<
+ typename CoordinateType,
+ std::size_t Dimension
+>
+struct access<model::rotation_quaternion<CoordinateType>, Dimension>
+{
+ static inline CoordinateType get(
+ model::rotation_quaternion<CoordinateType> const& v)
+ {
+ return v.template get<Dimension>();
+ }
+
+ static inline void set(
+ model::rotation_quaternion<CoordinateType> & v,
+ CoordinateType const& value)
+ {
+ v.template set<Dimension>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_ROTATION_QUATERNION_HPP
diff --git a/3party/boost/boost/geometry/extensions/algebra/geometries/vector.hpp b/3party/boost/boost/geometry/extensions/algebra/geometries/vector.hpp
new file mode 100644
index 0000000000..679fe547f1
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algebra/geometries/vector.hpp
@@ -0,0 +1,133 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_ALGEBRA_GEOMETRIES_VECTOR_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_VECTOR_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+template <typename CoordinateType, std::size_t DimensionCount>
+class vector
+{
+ BOOST_CONCEPT_ASSERT( (concept::Vector<vector>) );
+
+public:
+
+ /// @brief Default constructor, no initialization
+ inline vector()
+ {}
+
+ /// @brief Constructor to set one, two or three values
+ inline explicit vector(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
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename CoordinateType, std::size_t DimensionCount>
+struct tag<model::vector<CoordinateType, DimensionCount> >
+{
+ typedef vector_tag type;
+};
+
+template <typename CoordinateType, std::size_t DimensionCount>
+struct coordinate_type<model::vector<CoordinateType, DimensionCount> >
+{
+ typedef CoordinateType type;
+};
+
+template <typename CoordinateType, std::size_t DimensionCount>
+struct coordinate_system<model::vector<CoordinateType, DimensionCount> >
+{
+ typedef cs::cartesian type;
+};
+
+template <typename CoordinateType, std::size_t DimensionCount>
+struct dimension<model::vector<CoordinateType, DimensionCount> >
+ : boost::mpl::int_<DimensionCount>
+{};
+
+template
+<
+ typename CoordinateType,
+ std::size_t DimensionCount,
+ std::size_t Dimension
+>
+struct access<model::vector<CoordinateType, DimensionCount>, Dimension>
+{
+ static inline CoordinateType get(
+ model::vector<CoordinateType, DimensionCount> const& v)
+ {
+ return v.template get<Dimension>();
+ }
+
+ static inline void set(
+ model::vector<CoordinateType, DimensionCount> & v,
+ CoordinateType const& value)
+ {
+ v.template set<Dimension>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_VECTOR_HPP
diff --git a/3party/boost/boost/geometry/extensions/algorithms/connect.hpp b/3party/boost/boost/geometry/extensions/algorithms/connect.hpp
new file mode 100644
index 0000000000..7c5439b972
--- /dev/null
+++ b/3party/boost/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/core/tags.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/comparable_distance.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_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, Point, Point>::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_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, Point, Point>::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/3party/boost/boost/geometry/extensions/algorithms/detail/overlay/dissolver.hpp b/3party/boost/boost/geometry/extensions/algorithms/detail/overlay/dissolver.hpp
new file mode 100644
index 0000000000..f54dfecd25
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algorithms/detail/overlay/dissolver.hpp
@@ -0,0 +1,656 @@
+// 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/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 RescalePolicy,
+ typename OutputCollection
+ >
+ static inline bool check_negative(Geometry1 a, Geometry2 b, // pass-by-value
+ RescalePolicy const& rescale_policy,
+ 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,
+ typename segment_ratio_type<point_type, RescalePolicy>::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, rescale_policy, 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 RescalePolicy,
+ typename OutputCollection
+ >
+ static inline bool apply(Geometry1 const& a, Geometry2 const& b,
+ RescalePolicy const& rescale_policy,
+ 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, rescale_policy, output_collection);
+ }
+ else if (area_a < zero && area_b > zero)
+ {
+ return check_negative(b, a, rescale_policy, 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 RescalePolicy,
+ typename OutputCollection
+ >
+ static inline bool call_policy(
+ Element const& , Element const& ,
+ Geometry1 const& geometry1, Geometry2 const& geometry2,
+ RescalePolicy const& rescale_policy,
+ 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,
+ rescale_policy, output_collection);
+ }
+ return false;
+ }
+
+
+ template
+ <
+ int Dimension,
+ typename HelperVector,
+ typename IndexVector,
+ typename InputRange,
+ typename RescalePolicy,
+ typename OutputCollection,
+ typename Box
+ >
+ static inline bool divide_and_conquer(HelperVector& helper_vector
+ , IndexVector& index_vector
+ , InputRange const& input_range
+ , RescalePolicy const& rescale_policy
+ , 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, rescale_policy, output_collection, lower_box, changed, iteration + 1);
+ divide_and_conquer<1 - Dimension>(helper_vector,
+ upper_list, input_range, rescale_policy, 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),
+ rescale_policy,
+ 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),
+ rescale_policy,
+ 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),
+ rescale_policy,
+ 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),
+ rescale_policy,
+ 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 RescalePolicy,
+ typename OutputCollection
+ >
+ static inline void apply(InputRange const& input_range
+ , RescalePolicy const& rescale_policy
+ , 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, rescale_policy, 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();
+ 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/3party/boost/boost/geometry/extensions/algorithms/detail/overlay/split_rings.hpp b/3party/boost/boost/geometry/extensions/algorithms/detail/overlay/split_rings.hpp
new file mode 100644
index 0000000000..6f0067446b
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algorithms/detail/overlay/split_rings.hpp
@@ -0,0 +1,558 @@
+// 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/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);
+
+ typedef typename boost::range_const_iterator
+ <
+ typename interior_type<Polygon const>::type
+ >::type ring_iterator;
+
+ for (ring_iterator 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);
+
+ typedef typename boost::range_const_iterator
+ <
+ typename interior_type<Polygon const>::type
+ >::type ring_iterator;
+
+ for (ring_iterator 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/3party/boost/boost/geometry/extensions/algorithms/dissolve.hpp b/3party/boost/boost/geometry/extensions/algorithms/dissolve.hpp
new file mode 100644
index 0000000000..fea08e0492
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algorithms/dissolve.hpp
@@ -0,0 +1,307 @@
+// 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/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, typename RescalePolicy>
+ 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& ,
+ RescalePolicy 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 RescalePolicy, typename OutputIterator>
+ static inline OutputIterator apply(Geometry const& geometry,
+ RescalePolicy const& rescale_policy,
+ OutputIterator out)
+ {
+ typedef typename point_type<Geometry>::type point_type;
+
+ // Get the self-intersection points, including turns
+ typedef detail::overlay::traversal_turn_info
+ <
+ point_type,
+ typename segment_ratio_type<point_type, RescalePolicy>::type
+ > turn_info;
+
+ std::vector<turn_info> turns;
+ detail::dissolve::no_interrupt_policy policy;
+ geometry::self_turns
+ <
+ detail::overlay::assign_null_policy
+ >(geometry, rescale_policy, 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, rescale_policy,
+ 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,
+ rescale_policy,
+ turns, rings);
+
+ clear_visit_info(turns);
+
+ enrich_intersection_points<false, false>(turns,
+ detail::overlay::operation_intersection,
+ geometry, geometry, rescale_policy,
+ side_strategy_type());
+
+ // ... and for intersection
+ traverser::apply(geometry, geometry,
+ detail::overlay::operation_intersection,
+ rescale_policy,
+ turns, rings);
+
+ std::map<ring_identifier, detail::overlay::ring_turn_info> map;
+ get_ring_turn_info(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);
+
+ // 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);
+ id.multi_index++;
+ }
+ }
+
+ detail::overlay::assign_parents(geometry, rings, selected, true);
+ 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
+ : not_implemented<GeometryTag, GeometryOutTag>
+{};
+
+
+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>();
+
+ typedef typename geometry::rescale_policy_type
+ <
+ typename geometry::point_type<Geometry>::type
+ >::type rescale_policy_type;
+
+ rescale_policy_type robust_policy
+ = geometry::get_rescale_policy<rescale_policy_type>(geometry);
+
+ return dispatch::dissolve
+ <
+ typename tag<Geometry>::type,
+ typename tag<GeometryOut>::type,
+ Geometry,
+ GeometryOut
+ >::apply(geometry, robust_policy, 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, detail::no_rescale_policy(), std::back_inserter(output_collection));
+}
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DISSOLVE_HPP
diff --git a/3party/boost/boost/geometry/extensions/algorithms/distance_info.hpp b/3party/boost/boost/geometry/extensions/algorithms/distance_info.hpp
new file mode 100644
index 0000000000..2a0879cdf5
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algorithms/distance_info.hpp
@@ -0,0 +1,232 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2013 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2013 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2013 Mateusz Loskot, London, UK.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INFO_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DISTANCE_INFO_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.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/not_implemented.hpp>
+#include <boost/geometry/algorithms/detail/throw_on_empty_input.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/strategies/cartesian/distance_pythagoras.hpp>
+#include <boost/geometry/extensions/strategies/cartesian/distance_info.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance_info {
+
+
+template <typename Point1, typename Point2>
+struct point_point
+{
+ template <typename Strategy, typename Result>
+ static inline void apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy, Result& result)
+ {
+ result.real_distance
+ = result.projected_distance1
+ = result.projected_distance2
+ = strategy.apply_point_point(point1, point2);
+ // The projected point makes not really sense in point-point.
+ // We just assign one on the other
+ geometry::convert(point1, result.projected_point2);
+ geometry::convert(point2, result.projected_point1);
+ }
+};
+
+template <typename Point, typename Range>
+struct point_range
+{
+ template <typename Strategy, typename Result>
+ static inline void apply(Point const& point, Range const& range, Strategy const& strategy, Result& result)
+ {
+ // This should not occur (see exception on empty input below)
+ if (boost::begin(range) == boost::end(range))
+ {
+ return;
+ }
+
+ // line of one point: same case as point-point
+ typedef typename boost::range_const_iterator<Range>::type iterator_type;
+ iterator_type it = boost::begin(range);
+ iterator_type prev = it++;
+ if (it == boost::end(range))
+ {
+ point_point<Point, typename boost::range_value<Range const>::type>::apply(point, *prev, strategy, result);
+ return;
+ }
+
+ // Initialize with first segment
+ strategy.apply(point, *prev, *it, result);
+
+ // Check other segments
+ for(prev = it++; it != boost::end(range); prev = it++)
+ {
+ Result other;
+ strategy.apply(point, *prev, *it, other);
+ if (other.real_distance < result.real_distance)
+ {
+ result = other;
+ }
+ }
+ }
+};
+
+
+
+
+}} // namespace detail::distance_info
+#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,
+ bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
+>
+struct distance_info : not_implemented<Tag1, Tag2>
+{
+};
+
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename Tag1, typename Tag2
+>
+struct distance_info<Geometry1, Geometry2, Tag1, Tag2, true>
+{
+ template <typename Strategy, typename Result>
+ static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Strategy const& strategy, Result& result)
+ {
+ // Reversed version just calls dispatch with reversed arguments
+ distance_info
+ <
+ Geometry2, Geometry1, Tag2, Tag1, false
+ >::apply(geometry2, geometry1, strategy, result);
+ }
+
+};
+
+
+template<typename Point1, typename Point2>
+struct distance_info
+ <
+ Point1, Point2,
+ point_tag, point_tag, false
+ > : public detail::distance_info::point_point<Point1, Point2>
+{};
+
+
+template<typename Point, typename Segment>
+struct distance_info
+ <
+ Point, Segment,
+ point_tag, segment_tag,
+ false
+ >
+{
+ template <typename Strategy, typename Result>
+ static inline void apply(Point const& point, Segment const& segment,
+ Strategy const& strategy, Result& result)
+ {
+
+ 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]);
+
+ strategy.apply(point, p[0], p[1], result);
+ }
+};
+
+
+//template
+//<
+// typename Point, typename Ring,
+// typename Point
+//>
+//struct distance_info
+// <
+// point_tag, ring_tag,
+// Point, Ring,
+// Point
+// >
+// : detail::distance_info::point_range<Point, Ring, Point>
+//{};
+//
+//
+template<typename Point, typename Linestring>
+struct distance_info
+ <
+ Point, Linestring,
+ point_tag, linestring_tag,
+ false
+ >
+ : detail::distance_info::point_range<Point, Linestring>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+template <typename Geometry1, typename Geometry2, typename Result>
+inline void distance_info(Geometry1 const& geometry1, Geometry2 const& geometry2, Result& result)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ concept::check<typename Result::point_type>();
+
+ assert_dimension_equal<Geometry1, Geometry2>();
+ assert_dimension_equal<Geometry1, typename Result::point_type>();
+
+ detail::throw_on_empty_input(geometry1);
+ detail::throw_on_empty_input(geometry2);
+
+ strategy::distance::calculate_distance_info<> info_strategy;
+
+
+ dispatch::distance_info
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, info_strategy, result);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DISTANCE_INFO_HPP
diff --git a/3party/boost/boost/geometry/extensions/algorithms/midpoints.hpp b/3party/boost/boost/geometry/extensions/algorithms/midpoints.hpp
new file mode 100644
index 0000000000..6c669d7d14
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/algorithms/offset.hpp b/3party/boost/boost/geometry/extensions/algorithms/offset.hpp
new file mode 100644
index 0000000000..ec8943d2aa
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algorithms/offset.hpp
@@ -0,0 +1,193 @@
+// 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/config.hpp>
+
+#include <boost/range/functions.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp>
+#include <boost/geometry/strategies/buffer.hpp>
+#include <boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp>
+#include <boost/geometry/strategies/agnostic/buffer_end_skip.hpp>
+#include <boost/geometry/strategies/cartesian/buffer_side.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/geometries/segment.hpp>
+
+#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace offset
+{
+
+
+template
+<
+ typename Range,
+ typename RangeOut
+>
+struct offset_range
+{
+ typedef geometry::detail::buffer::buffer_range
+ <
+ Range
+ > per_range;
+
+ template
+ <
+ typename Collection,
+ typename DistanceStrategy,
+ typename SideStrategy,
+ typename JoinStrategy,
+ typename EndStrategy,
+ typename RobustPolicy
+ >
+ static inline void apply(Collection& collection, Range const& range,
+ DistanceStrategy const& distance_strategy,
+ SideStrategy const& side_strategy,
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy,
+ RobustPolicy const& robust_policy,
+ bool reverse)
+ {
+ collection.start_new_ring();
+ typedef typename point_type<RangeOut>::type output_point_type;
+ output_point_type first_p1, first_p2, last_p1, last_p2;
+
+ if (reverse)
+ {
+ per_range::iterate(collection, 0, boost::rbegin(range), boost::rend(range),
+ strategy::buffer::buffer_side_left,
+ distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
+ first_p1, first_p2, last_p1, last_p2);
+ }
+ else
+ {
+ per_range::iterate(collection, 0, boost::begin(range), boost::end(range),
+ strategy::buffer::buffer_side_left,
+ distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
+ first_p1, first_p2, last_p1, last_p2);
+ }
+ collection.finish_ring();
+ }
+};
+
+}} // namespace detail::offset
+#endif
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryTag,
+ typename GeometryOutTag,
+ typename Geometry,
+ typename GeometryOut
+>
+struct offset
+{};
+
+
+template
+<
+ typename Geometry,
+ typename GeometryOut
+>
+struct offset
+ <
+ linestring_tag,
+ linestring_tag,
+ Geometry,
+ GeometryOut
+ >
+ : detail::offset::offset_range
+ <
+ Geometry,
+ GeometryOut
+ >
+{};
+
+
+} // 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_strategy,
+ Distance const& distance)
+{
+ concept::check<Geometry const>();
+ concept::check<GeometryOut>();
+
+ typedef typename geometry::point_type<Geometry>::type point_type;
+
+ detail::no_rescale_policy robust_policy;
+
+ detail::buffer::buffered_piece_collection
+ <
+ model::ring<point_type>,
+ detail::no_rescale_policy
+ > collection(robust_policy);
+
+ bool reverse = distance < 0;
+ strategy::buffer::distance_asymmetric
+ <
+ typename geometry::coordinate_type<Geometry>::type
+ > distance_strategy(geometry::math::abs(distance),
+ geometry::math::abs(distance));
+
+ strategy::buffer::end_skip
+ <
+ point_type,
+ point_type
+ > end_strategy;
+
+ strategy::buffer::buffer_side side_strategy;
+
+ dispatch::offset
+ <
+ typename tag<Geometry>::type,
+ typename tag<GeometryOut>::type,
+ Geometry,
+ GeometryOut
+ >::apply(collection,
+ geometry,
+ distance_strategy,
+ side_strategy,
+ join_strategy,
+ end_strategy,
+ robust_policy,
+ reverse);
+
+ // TODO collection.template assign<GeometryOut>(out);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_OFFSET_HPP
diff --git a/3party/boost/boost/geometry/extensions/algorithms/offset_appender.hpp b/3party/boost/boost/geometry/extensions/algorithms/offset_appender.hpp
new file mode 100644
index 0000000000..594ee235cc
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algorithms/offset_appender.hpp
@@ -0,0 +1,96 @@
+// 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_OFFSET_APPENDER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OFFSET_APPENDER_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace offset
+{
+
+// Appends points to an output range (linestring/ring).
+template
+ <
+ typename Range
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , typename Mapper
+#endif
+ >
+struct offset_appender
+{
+ typedef Range range_type;
+
+ typedef typename geometry::point_type<Range>::type point_type;
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ Mapper const& m_mapper;
+ inline offset_appender(Range& r, Mapper const& mapper)
+ : m_range(r)
+ , m_mapper(mapper)
+#else
+ inline offset_appender(Range& r)
+ : m_range(r)
+#endif
+
+ {}
+
+ inline void append(point_type const& point)
+ {
+ do_append(point);
+ }
+
+ inline void append_begin_join(point_type const& point)
+ {
+ do_append(point);
+ }
+
+ inline void append_end_join(point_type const& point)
+ {
+ do_append(point);
+ }
+
+ inline void append_begin_hooklet(point_type const& point)
+ {
+ do_append(point);
+ }
+
+ inline void append_end_hooklet(point_type const& point)
+ {
+ do_append(point);
+ }
+
+
+private :
+
+ Range& m_range;
+
+ inline void do_append(point_type const& point)
+ {
+ m_range.push_back(point);
+ }
+};
+
+
+}} // namespace detail::offset
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OFFSET_APPENDER_HPP
diff --git a/3party/boost/boost/geometry/extensions/algorithms/parse.hpp b/3party/boost/boost/geometry/extensions/algorithms/parse.hpp
new file mode 100644
index 0000000000..db2d75caad
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/algorithms/point_on_line.hpp b/3party/boost/boost/geometry/extensions/algorithms/point_on_line.hpp
new file mode 100644
index 0000000000..77bb23ff55
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/algorithms/remove_holes_if.hpp b/3party/boost/boost/geometry/extensions/algorithms/remove_holes_if.hpp
new file mode 100644
index 0000000000..5d11d34046
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/algorithms/remove_holes_if.hpp
@@ -0,0 +1,163 @@
+// 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/detail/multi_modify_with_predicate.hpp>
+#include <boost/geometry/algorithms/perimeter.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tags.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 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/3party/boost/boost/geometry/extensions/algorithms/remove_marked.hpp b/3party/boost/boost/geometry/extensions/algorithms/remove_marked.hpp
new file mode 100644
index 0000000000..2ab8c3184e
--- /dev/null
+++ b/3party/boost/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
+
+// PROBABLY OBSOLETE
+// as mark_spikes is now replaced by remove_spikes
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tags.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/3party/boost/boost/geometry/extensions/algorithms/selected.hpp b/3party/boost/boost/geometry/extensions/algorithms/selected.hpp
new file mode 100644
index 0000000000..8890d6ab05
--- /dev/null
+++ b/3party/boost/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
+ <
+ point_tag, segment_tag, P, PS
+ >::type strategy_type;
+ typedef typename strategy::distance::services::return_type<strategy_type, P, PS>::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/3party/boost/boost/geometry/extensions/arithmetic/cross_product.hpp b/3party/boost/boost/geometry/extensions/arithmetic/cross_product.hpp
new file mode 100644
index 0000000000..879ef8a20d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/arithmetic/cross_product.hpp
@@ -0,0 +1,110 @@
+// 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_EXTENSIONS_ARITHMETIC_CROSS_PRODUCT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ARITHMETIC_CROSS_PRODUCT_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 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 vectors.
+\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/3party/boost/boost/geometry/extensions/astronomy/core/cs.hpp b/3party/boost/boost/geometry/extensions/astronomy/core/cs.hpp
new file mode 100644
index 0000000000..c5833a326c
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmath.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmath.h
new file mode 100644
index 0000000000..37c971f6aa
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathbig.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathbig.h
new file mode 100644
index 0000000000..dc3e98c40d
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathint.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathint.h
new file mode 100644
index 0000000000..ad306f01ab
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathmisc.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathmisc.h
new file mode 100644
index 0000000000..330a43a468
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathobjects.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathobjects.h
new file mode 100644
index 0000000000..c35026bbd0
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathparser.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathparser.h
new file mode 100644
index 0000000000..4b2243f349
--- /dev/null
+++ b/3party/boost/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@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, &param) != 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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmaththreads.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmaththreads.h
new file mode 100644
index 0000000000..586227f2fc
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathtypes.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathtypes.h
new file mode 100644
index 0000000000..539c100358
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint.h
new file mode 100644
index 0000000000..d0f6df132c
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_noasm.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_noasm.h
new file mode 100644
index 0000000000..07c73fc499
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86.h
new file mode 100644
index 0000000000..1dd087f524
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64.h b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64.h
new file mode 100644
index 0000000000..188fc5e7bd
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64_msvc.asm b/3party/boost/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64_msvc.asm
new file mode 100644
index 0000000000..b7c85c2b84
--- /dev/null
+++ b/3party/boost/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@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/3party/boost/boost/geometry/extensions/contrib/ttmath_stub.hpp b/3party/boost/boost/geometry/extensions/contrib/ttmath_stub.hpp
new file mode 100644
index 0000000000..cb53fc114c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/contrib/ttmath_stub.hpp
@@ -0,0 +1,373 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost 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);
+ }
+
+ // needed in order to work with boost::geometry::math::mod
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> mod(Big<Exponent, Mantissa> const& x,
+ Big<Exponent, Mantissa> const& y)
+ {
+ return Mod(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)
+ {}
+
+ // unary operator+() is implemented for completeness
+ inline ttmath_big const& operator+() const
+ {
+ return *this;
+ }
+
+ // needed in order to work with boost::geometry::math::abs
+ inline ttmath_big operator-() const
+ {
+ return ttmath::Big<1,4>::operator-();
+ }
+
+ /*
+ inline operator double() const
+ {
+ return atof(this->ToString().c_str());
+ }
+
+ inline operator int() const
+ {
+ return atol(ttmath::Round(*this).ToString().c_str());
+ }
+ */
+};
+
+
+// arithmetic operators for ttmath_big objects, defined as free functions
+inline ttmath_big operator+(ttmath_big const& x, ttmath_big const& y)
+{
+ return static_cast<ttmath::Big<1,4> const&>(x).operator+(y);
+}
+
+inline ttmath_big operator-(ttmath_big const& x, ttmath_big const& y)
+{
+ return static_cast<ttmath::Big<1,4> const&>(x).operator-(y);
+}
+
+inline ttmath_big operator*(ttmath_big const& x, ttmath_big const& y)
+{
+ return static_cast<ttmath::Big<1,4> const&>(x).operator*(y);
+}
+
+inline ttmath_big operator/(ttmath_big const& x, ttmath_big const& y)
+{
+ return static_cast<ttmath::Big<1,4> const&>(x).operator/(y);
+}
+
+
+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_half_pi<ttmath::Big<Exponent, Mantissa> >
+ {
+ static inline ttmath::Big<Exponent, Mantissa> apply()
+ {
+ static ttmath::Big<Exponent, Mantissa> const half_pi(
+ "1.57079632679489661923132169163975144209858469968755291048747229615390820314310449931401741267105853399107404325664115332354692230477529111586267970406424055872514205135096926055277982231147447746519098");
+ return half_pi;
+ }
+ };
+
+ // 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;
+ }
+ };
+
+ // Partial specialization for ttmath
+ template <ttmath::uint Exponent, ttmath::uint Mantissa>
+ struct define_two_pi<ttmath::Big<Exponent, Mantissa> >
+ {
+ static inline ttmath::Big<Exponent, Mantissa> apply()
+ {
+ static ttmath::Big<Exponent, Mantissa> const two_pi(
+ "6.28318530717958647692528676655900576839433879875021164194988918461563281257241799725606965068423413596429617302656461329418768921910116446345071881625696223490056820540387704221111928924589790986076392");
+ return two_pi;
+ }
+ };
+
+ template <>
+ struct define_half_pi<ttmath_big>
+ : public define_half_pi<ttmath::Big<1,4> >
+ {};
+
+ template <>
+ struct define_pi<ttmath_big>
+ : public define_pi<ttmath::Big<1,4> >
+ {};
+
+ template <>
+ struct define_two_pi<ttmath_big>
+ : public define_two_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/3party/boost/boost/geometry/extensions/gis/geographic/core/cs.hpp b/3party/boost/boost/geometry/extensions/gis/geographic/core/cs.hpp
new file mode 100644
index 0000000000..878241e1ee
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/gis/geographic/strategies/area_huiller_earth.hpp b/3party/boost/boost/geometry/extensions/gis/geographic/strategies/area_huiller_earth.hpp
new file mode 100644
index 0000000000..8116279f4a
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/gis/geographic/strategies/distance_cross_track.hpp b/3party/boost/boost/geometry/extensions/gis/geographic/strategies/distance_cross_track.hpp
new file mode 100644
index 0000000000..4e00c4b74c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/geographic/strategies/distance_cross_track.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_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<point_tag, segment_tag, Point, PointOfSegment, geographic_tag, geographic_tag, Strategy>
+{
+ typedef cross_track
+ <
+ void,
+ typename boost::mpl::if_
+ <
+ boost::is_void<Strategy>,
+ typename default_strategy
+ <
+ point_tag, 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/3party/boost/boost/geometry/extensions/gis/geographic/strategies/dms_parser.hpp b/3party/boost/boost/geometry/extensions/gis/geographic/strategies/dms_parser.hpp
new file mode 100644
index 0000000000..5fb829c525
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/geographic/strategies/dms_parser.hpp
@@ -0,0 +1,278 @@
+// 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>
+
+#if !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
+#include <boost/lexical_cast.hpp>
+#endif // !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
+
+#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)
+ {
+#if !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
+ dms.dms[I] = boost::lexical_cast<double>(value.c_str());
+#else // !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
+ dms.dms[I] = std::atof(value.c_str());
+#endif // !defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
+ 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);
+
+ double const d2r = math::d2r<double>();
+ double const r2d = math::r2d<double>();
+
+ return dms_result(factor *
+ (in_radian && as_radian
+ ? dms.dms[0]
+ : in_radian && ! as_radian
+ ? dms.dms[0] * r2d
+ : ! in_radian && as_radian
+ ? dms.dms[0] * d2r + dms.dms[1] * d2r / 60.0 + dms.dms[2] * 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 CoordinateSystem>
+struct strategy_parse<geographic_tag, CoordinateSystem<degree> >
+{
+ typedef strategy::dms_parser<false> type;
+};
+
+
+template <template<typename> class CoordinateSystem>
+struct strategy_parse<geographic_tag, CoordinateSystem<radian> >
+{
+ typedef strategy::dms_parser<true> type;
+};
+
+#endif
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_DMS_PARSER_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/io/shapelib/dbf_write_attribute.hpp b/3party/boost/boost/geometry/extensions/gis/io/shapelib/dbf_write_attribute.hpp
new file mode 100644
index 0000000000..4ed21de768
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp b/3party/boost/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp
new file mode 100644
index 0000000000..eeabbc891d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp
@@ -0,0 +1,154 @@
+// 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();
+ }
+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/3party/boost/boost/geometry/extensions/gis/io/shapelib/shape_reader.hpp b/3party/boost/boost/geometry/extensions/gis/io/shapelib/shape_reader.hpp
new file mode 100644
index 0000000000..4c1ca7b431
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/gis/io/shapelib/shp_create_object.hpp b/3party/boost/boost/geometry/extensions/gis/io/shapelib/shp_create_object.hpp
new file mode 100644
index 0000000000..0c8ad37e47
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/io/shapelib/shp_create_object.hpp
@@ -0,0 +1,232 @@
+// 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/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);
+
+ typedef typename boost::range_const_iterator
+ <
+ typename interior_type<Polygon const>::type
+ >::type ring_iterator;
+
+ for (ring_iterator 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/3party/boost/boost/geometry/extensions/gis/io/shapelib/shp_create_object_multi.hpp b/3party/boost/boost/geometry/extensions/gis/io/shapelib/shp_create_object_multi.hpp
new file mode 100644
index 0000000000..b265231d30
--- /dev/null
+++ b/3party/boost/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/core/tags.hpp>
+#include <boost/geometry/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/3party/boost/boost/geometry/extensions/gis/io/shapelib/shp_read_object.hpp b/3party/boost/boost/geometry/extensions/gis/io/shapelib/shp_read_object.hpp
new file mode 100644
index 0000000000..73204a9536
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/gis/io/veshape/write_veshape.hpp b/3party/boost/boost/geometry/extensions/gis/io/veshape/write_veshape.hpp
new file mode 100644
index 0000000000..4b4caffc04
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp b/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp
new file mode 100644
index 0000000000..dbf060217a
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp b/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp
new file mode 100644
index 0000000000..b854473478
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp
@@ -0,0 +1,176 @@
+// 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_ogc
+{
+ enum enum_t
+ {
+ point = 1,
+ linestring = 2,
+ polygon = 3
+
+ // TODO: Not implemented
+ //multipoint = 4,
+ //multilinestring = 5,
+ //multipolygon = 6,
+ //collection = 7
+ };
+};
+
+struct geometry_type_ewkt
+{
+ enum enum_t
+ {
+ point = 1,
+ linestring = 2,
+ polygon = 3,
+
+ // TODO: Not implemented
+ //multipoint = 4,
+ //multilinestring = 5,
+ //multipolygon = 6,
+ //collection = 7
+
+
+ pointz = 1001,
+ linestringz = 1002,
+ polygonz = 1003
+ };
+};
+
+struct ogc_policy
+{
+};
+
+struct ewkt_policy
+{
+};
+
+template
+<
+ typename Geometry,
+ geometry_type_ogc::enum_t OgcType,
+ std::size_t Dim = dimension<Geometry>::value
+>
+struct geometry_type_impl
+{
+ static bool check(boost::uint32_t value)
+ {
+ return value == get();
+ }
+
+ static boost::uint32_t get()
+ {
+ return OgcType;
+ }
+};
+
+template
+<
+ typename Geometry,
+ geometry_type_ogc::enum_t OgcType
+>
+struct geometry_type_impl<Geometry, OgcType, 3>
+{
+ static bool check(boost::uint32_t value)
+ {
+ return value == get();
+ }
+
+ static boost::uint32_t get()
+ {
+ return 1000 + OgcType;
+ }
+};
+
+template
+<
+ typename Geometry,
+ typename CheckPolicy = ogc_policy,
+ typename Tag = typename tag<Geometry>::type
+>
+struct geometry_type : not_implemented<Tag>
+{
+};
+
+template <typename Geometry, typename CheckPolicy>
+struct geometry_type<Geometry, CheckPolicy, point_tag>
+ : geometry_type_impl<Geometry, geometry_type_ogc::point>
+{};
+
+template <typename Geometry, typename CheckPolicy>
+struct geometry_type<Geometry, CheckPolicy, linestring_tag>
+ : geometry_type_impl<Geometry, geometry_type_ogc::linestring>
+{};
+
+template <typename Geometry, typename CheckPolicy>
+struct geometry_type<Geometry, CheckPolicy, polygon_tag>
+ : geometry_type_impl<Geometry, geometry_type_ogc::polygon>
+{};
+
+}} // namespace detail::wkb
+#endif // DOXYGEN_NO_IMPL
+
+}} // namespace boost::geometry
+#endif // BOOST_GEOMETRY_IO_WKB_DETAIL_OGC_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp b/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp
new file mode 100644
index 0000000000..8c649d6592
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp
@@ -0,0 +1,301 @@
+// 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 <algorithm>
+#include <cassert>
+#include <cstddef>
+#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/assert.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;
+ }
+};
+
+template <typename Geometry>
+struct geometry_type_parser
+{
+ template <typename Iterator>
+ static bool parse(Iterator& it, Iterator end,
+ byte_order_type::enum_t order)
+ {
+ boost::uint32_t value;
+ if (value_parser<boost::uint32_t>::parse(it, end, value, order))
+ {
+ return geometry_type<Geometry>::check(value);
+ }
+ return false;
+ }
+};
+
+template <typename P,
+ std::size_t I = 0,
+ std::size_t N = dimension<P>::value>
+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, std::size_t 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
+ }
+};
+
+template <typename P>
+struct point_parser
+{
+ template <typename Iterator>
+ static bool parse(Iterator& it, Iterator end, P& point,
+ byte_order_type::enum_t order)
+ {
+ if (geometry_type_parser<P>::parse(it, end, order))
+ {
+ if (it != end)
+ {
+ parsing_assigner<P>::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;
+ BOOST_GEOMETRY_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;
+
+ // 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>::run(it, end, point_buffer, order);
+ boost::geometry::append(container, point_buffer);
+ ++points_parsed;
+ }
+
+ if (container_size != points_parsed)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ 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)
+ {
+ if (!geometry_type_parser<L>::parse(it, end, order))
+ {
+ return false;
+ }
+
+ BOOST_GEOMETRY_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)
+ {
+ if (!geometry_type_parser<Polygon>::parse(it, end, order))
+ {
+ return false;
+ }
+
+ boost::uint32_t num_rings(0);
+ if (!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)
+ {
+ 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/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/writer.hpp b/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/writer.hpp
new file mode 100644
index 0000000000..7db961404b
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/io/wkb/detail/writer.hpp
@@ -0,0 +1,234 @@
+// Boost.Geometry
+//
+// Copyright (c) 2015 Mats Taraldsvik.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_WRITER_HPP
+#define BOOST_GEOMETRY_IO_WKB_DETAIL_WRITER_HPP
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <limits>
+
+#include <boost/concept_check.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/range.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_same.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_writer
+ {
+ typedef T value_type;
+
+ template <typename OutputIterator>
+ static bool write(T const& value,
+ OutputIterator& iter,
+ byte_order_type::enum_t byte_order)
+ {
+ endian::endian_value<T> parsed_value(value);
+
+// if (byte_order_type::xdr == byte_order)
+// {
+// parsed_value.template store<endian::big_endian_tag>(iter);
+// }
+// else if (byte_order_type::ndr == byte_order)
+// {
+// parsed_value.template store<endian::little_endian_tag>(iter);
+// }
+// else
+// {
+ parsed_value.template store<endian::native_endian_tag>(iter);
+// }
+
+ return true;
+ }
+ };
+
+ template
+ <
+ typename Point,
+ std::size_t I = 0,
+ std::size_t N = dimension<Point>::value
+ >
+ struct writer_assigner
+ {
+ template <typename OutputIterator>
+ static void run(Point const& point,
+ OutputIterator& iter,
+ byte_order_type::enum_t byte_order)
+ {
+ // NOTE: coordinates of any type are converted to double
+
+ value_writer<double>::write(geometry::get<I>(point),
+ iter,
+ byte_order);
+
+ writer_assigner<Point, I+1, N>::run(point, iter, byte_order);
+ }
+ };
+
+ template <typename Point, std::size_t N>
+ struct writer_assigner<Point, N, N>
+ {
+ template <typename OutputIterator>
+ static void run(Point const& /*point*/,
+ OutputIterator& /*iter*/,
+ byte_order_type::enum_t /*byte_order*/)
+ {
+ // terminate
+ }
+ };
+
+ template <typename Point>
+ struct point_writer
+ {
+ template <typename OutputIterator>
+ static bool write(Point const& point,
+ OutputIterator& iter,
+ byte_order_type::enum_t byte_order)
+ {
+ // write endian type
+ value_writer<uint8_t>::write(byte_order, iter, byte_order);
+
+ // write geometry type
+ uint32_t type = geometry_type<Point>::get();
+ value_writer<uint32_t>::write(type, iter, byte_order);
+
+ // write point's x, y, z
+ writer_assigner<Point>::run(point, iter, byte_order);
+
+ return true;
+ }
+ };
+
+ template <typename Linestring>
+ struct linestring_writer
+ {
+ template <typename OutputIterator>
+ static bool write(Linestring const& linestring,
+ OutputIterator& iter,
+ byte_order_type::enum_t byte_order)
+ {
+ // write endian type
+ value_writer<uint8_t>::write(byte_order, iter, byte_order);
+
+ // write geometry type
+ uint32_t type = geometry_type<Linestring>::get();
+ value_writer<uint32_t>::write(type, iter, byte_order);
+
+ // write num points
+ uint32_t num_points = boost::size(linestring);
+ value_writer<uint32_t>::write(num_points, iter, byte_order);
+
+ for(typename boost::range_iterator<Linestring const>::type
+ point_iter = boost::begin(linestring);
+ point_iter != boost::end(linestring);
+ ++point_iter)
+ {
+ // write point's x, y, z
+ writer_assigner<typename point_type<Linestring>::type>
+ ::run(*point_iter, iter, byte_order);
+ }
+
+ return true;
+ }
+ };
+
+ template <typename Polygon>
+ struct polygon_writer
+ {
+ template <typename OutputIterator>
+ static bool write(Polygon const& polygon,
+ OutputIterator& iter,
+ byte_order_type::enum_t byte_order)
+ {
+ // write endian type
+ value_writer<uint8_t>::write(byte_order, iter, byte_order);
+
+ // write geometry type
+ uint32_t type = geometry_type<Polygon>::get();
+ value_writer<uint32_t>::write(type, iter, byte_order);
+
+ // write num rings
+ uint32_t num_rings = 1 + geometry::num_interior_rings(polygon);
+ value_writer<uint32_t>::write(num_rings, iter, byte_order);
+
+ // write exterior ring
+ typedef typename geometry::ring_type<Polygon const>::type
+ ring_type;
+
+ typename geometry::ring_return_type<Polygon const>::type
+ exterior_ring = geometry::exterior_ring(polygon);
+
+ value_writer<uint32_t>::write(geometry::num_points(exterior_ring),
+ iter,
+ byte_order);
+
+ for(typename boost::range_iterator<ring_type const>::type
+ point_iter = boost::begin(exterior_ring);
+ point_iter != boost::end(exterior_ring);
+ ++point_iter)
+ {
+ // write point's x, y, z
+ writer_assigner<typename point_type<Polygon>::type>
+ ::run(*point_iter, iter, byte_order);
+ }
+
+ // write interor rings
+ typedef typename geometry::interior_type<Polygon const>::type
+ interior_rings_type;
+
+ typename geometry::interior_return_type<Polygon const>::type
+ interior_rings = geometry::interior_rings(polygon);
+
+ for(typename boost::range_iterator<interior_rings_type const>::type
+ ring_iter = boost::begin(interior_rings);
+ ring_iter != boost::end(interior_rings);
+ ++ring_iter)
+ {
+ value_writer<uint32_t>::write(geometry::num_points(*ring_iter),
+ iter,
+ byte_order);
+
+ for(typename boost::range_iterator<ring_type const>::type
+ point_iter = boost::begin(*ring_iter);
+ point_iter != boost::end(*ring_iter);
+ ++point_iter)
+ {
+ // write point's x, y, z
+ writer_assigner<typename point_type<Polygon>::type>
+ ::run(*point_iter, iter, byte_order);
+ }
+ }
+
+ return true;
+ }
+ };
+
+}} // namespace detail::wkb
+#endif // DOXYGEN_NO_IMPL
+
+}} // namespace boost::geometry
+#endif // BOOST_GEOMETRY_IO_WKB_DETAIL_WRITER_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/io/wkb/read_wkb.hpp b/3party/boost/boost/geometry/extensions/gis/io/wkb/read_wkb.hpp
new file mode 100644
index 0000000000..69662b584e
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/gis/io/wkb/utility.hpp b/3party/boost/boost/geometry/extensions/gis/io/wkb/utility.hpp
new file mode 100644
index 0000000000..99bcf92e5e
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/io/wkb/utility.hpp
@@ -0,0 +1,99 @@
+// 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>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+#include <boost/geometry/core/assert.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.
+ typename std::iterator_traits<Iterator>::difference_type
+ diff = std::distance(begin, end);
+ BOOST_GEOMETRY_ASSERT(diff > 0);
+ return hex.size() == 2 * std::string::size_type(diff);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_WKB_UTILITY_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/io/wkb/write_wkb.hpp b/3party/boost/boost/geometry/extensions/gis/io/wkb/write_wkb.hpp
new file mode 100644
index 0000000000..b67299b20e
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/io/wkb/write_wkb.hpp
@@ -0,0 +1,128 @@
+// Boost.Geometry
+//
+// Copyright (c) 2015 Mats Taraldsvik.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_WRITE_WKB_HPP
+#define BOOST_GEOMETRY_IO_WKB_WRITE_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/writer.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename G>
+struct write_wkb
+{
+};
+
+template <typename G>
+struct write_wkb<point_tag, G>
+{
+ template <typename OutputIterator>
+ static inline bool write(const G& geometry, OutputIterator iter,
+ detail::wkb::byte_order_type::enum_t byte_order)
+ {
+ return detail::wkb::point_writer<G>::write(geometry, iter, byte_order);
+ }
+};
+
+template <typename G>
+struct write_wkb<linestring_tag, G>
+{
+ template <typename OutputIterator>
+ static inline bool write(const G& geometry, OutputIterator iter,
+ detail::wkb::byte_order_type::enum_t byte_order)
+ {
+ return detail::wkb::linestring_writer<G>::write(geometry, iter, byte_order);
+ }
+};
+
+template <typename G>
+struct write_wkb<polygon_tag, G>
+{
+ template <typename OutputIterator>
+ static inline bool write(const G& geometry, OutputIterator iter,
+ detail::wkb::byte_order_type::enum_t byte_order)
+ {
+ return detail::wkb::polygon_writer<G>::write(geometry, iter, byte_order);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+template <typename G, typename OutputIterator>
+inline bool write_wkb(const G& geometry, OutputIterator iter)
+{
+ // The WKB is written to an OutputIterator.
+ BOOST_STATIC_ASSERT((
+ boost::is_convertible
+ <
+ typename std::iterator_traits<OutputIterator>::iterator_category,
+ const std::output_iterator_tag&
+ >::value));
+
+// Will write in the native byte order
+#ifdef BOOST_BIG_ENDIAN
+ detail::wkb::byte_order_type::enum_t byte_order = detail::wkb::byte_order_type::xdr;
+#else
+ detail::wkb::byte_order_type::enum_t byte_order = detail::wkb::byte_order_type::ndr;
+#endif
+
+ if
+ (!dispatch::write_wkb
+ <
+ typename tag<G>::type,
+ G
+ >::write(geometry, iter, byte_order))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+// template <typename G, typename OutputIterator>
+// inline bool write_wkb(G& geometry, OutputIterator iter,
+// detail::wkb::byte_order_type::enum_t source_byte_order,
+// detail::wkb::byte_order_type::enum_t target_byte_order)
+// {
+// // The WKB is written to an OutputIterator.
+// BOOST_STATIC_ASSERT((
+// boost::is_convertible
+// <
+// typename std::iterator_traits<OutputIterator>::iterator_category,
+// const std::output_iterator_tag&
+// >::value));
+//
+// if
+// (
+// !dispatch::write_wkb
+// <
+// typename tag<G>::type,
+// G
+// >::write(geometry, iter, byte_order)
+// )
+// {
+// return false;
+// }
+//
+// return true;
+// }
+
+}} // namespace boost::geometry
+#endif // BOOST_GEOMETRY_IO_WKB_WRITE_WKB_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/latlong/detail/graticule.hpp b/3party/boost/boost/geometry/extensions/gis/latlong/detail/graticule.hpp
new file mode 100644
index 0000000000..84f519e72b
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/gis/latlong/latlong.hpp b/3party/boost/boost/geometry/extensions/gis/latlong/latlong.hpp
new file mode 100644
index 0000000000..61c16e80ef
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/latlong/latlong.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_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/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/3party/boost/boost/geometry/extensions/gis/latlong/point_ll.hpp b/3party/boost/boost/geometry/extensions/gis/latlong/point_ll.hpp
new file mode 100644
index 0000000000..1740d1ab8c
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/gis/projections/epsg.hpp b/3party/boost/boost/geometry/extensions/gis/projections/epsg.hpp
new file mode 100644
index 0000000000..560e3b4369
--- /dev/null
+++ b/3party/boost/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 projections
+{
+
+
+#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::projections
+
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/epsg_traits.hpp b/3party/boost/boost/geometry/extensions/gis/projections/epsg_traits.hpp
new file mode 100644
index 0000000000..d0140b3094
--- /dev/null
+++ b/3party/boost/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 projections
+{
+
+/*!
+ \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::projections
+
+
+#endif
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/factory.hpp b/3party/boost/boost/geometry/extensions/gis/projections/factory.hpp
new file mode 100644
index 0000000000..6f5ff26bd0
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/factory.hpp
@@ -0,0 +1,267 @@
+// 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>
+#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/etmerc.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>
+#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/healpix.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/krovak.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/igh.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/imw_p.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/isea.hpp>
+#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/natearth.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>
+#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/qsc.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 projections
+{
+
+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::etmerc_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::healpix_init(*this);
+ detail::krovak_init(*this);
+ detail::igh_init(*this);
+ detail::imw_p_init(*this);
+ detail::isea_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::natearth_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::qsc_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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_FACTORY_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/aasincos.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/aasincos.hpp
new file mode 100644
index 0000000000..316de4816a
--- /dev/null
+++ b/3party/boost/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 projections
+{
+
+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 ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>());
+ }
+
+ 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 ? geometry::math::pi<double>() : 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::projections
+
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_AASINCOS_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/adjlon.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/adjlon.hpp
new file mode 100644
index 0000000000..7f0c9ac4ca
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/adjlon.hpp
@@ -0,0 +1,70 @@
+// 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 <boost/math/constants/constants.hpp>
+#include <boost/geometry/util/math.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+
+namespace detail
+{
+
+/* reduce argument to range +/- PI */
+template <typename T>
+inline T adjlon (T lon)
+{
+ if (geometry::math::abs(lon) <= boost::math::constants::pi<T>())
+ {
+ return lon;
+ }
+
+ /* adjust to 0..2pi rad */
+ lon += boost::math::constants::pi<T>();
+ /* remove integral # of 'revolutions'*/
+ lon -= boost::math::constants::two_pi<T>() *
+ std::floor(lon / boost::math::constants::two_pi<T>());
+ /* adjust back to -pi..pi rad */
+ lon -= boost::math::constants::pi<T>();
+
+ return lon;
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_ADJLON_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp
new file mode 100644
index 0000000000..8ee12119a6
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/base_dynamic.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_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
+
+#include <string>
+
+
+#include <boost/geometry/extensions/gis/projections/projection.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+
+#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 const& params() const { return m_proj.params(); }
+
+ virtual P& mutable_params() { return m_proj.mutable_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& , LL& ) const
+ {
+ // exception?
+ return false;
+ }
+ virtual void inv(XY_T& , XY_T& , LL_T& , LL_T& ) const
+ {
+ // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/base_static.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/base_static.hpp
new file mode 100644
index 0000000000..15e86aab3a
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/base_static.hpp
@@ -0,0 +1,110 @@
+// 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 projections
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Base-template-forward
+template <typename Prj, typename LL, typename XY, typename P>
+struct base_t_f
+{
+public:
+
+ typedef LL geographic_point_type; ///< latlong point type
+ typedef XY cartesian_point_type; ///< xy point type
+
+ inline base_t_f(Prj const& prj, P const& params)
+ : m_par(params), m_prj(prj)
+ {}
+
+ inline P const& params() const { return m_par; }
+
+ inline P& mutable_params() { 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::projections
+
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_STATIC_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/factory_entry.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/factory_entry.hpp
new file mode 100644
index 0000000000..0b8dba67e7
--- /dev/null
+++ b/3party/boost/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 projections
+{
+
+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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_FACTORY_ENTRY_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/function_overloads.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/function_overloads.hpp
new file mode 100644
index 0000000000..3a853380d7
--- /dev/null
+++ b/3party/boost/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 projections
+{
+
+// 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_FUNCTION_OVERLOADS_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_auth.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_auth.hpp
new file mode 100644
index 0000000000..7e8d9244dc
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_auth.hpp
@@ -0,0 +1,88 @@
+// 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>
+
+#include <boost/geometry/core/assert.hpp>
+
+namespace boost { namespace geometry { namespace projections {
+
+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 bool pj_authset(double es, double* APA)
+{
+ BOOST_GEOMETRY_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;
+ }
+ return true;
+}
+
+inline double pj_authlat(double beta, const double* APA)
+{
+ BOOST_GEOMETRY_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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_AUTH_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_datum_set.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_datum_set.hpp
new file mode 100644
index 0000000000..66b56355aa
--- /dev/null
+++ b/3party/boost/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 projections {
+
+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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUM_SET_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_datums.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_datums.hpp
new file mode 100644
index 0000000000..539b9d8bfd
--- /dev/null
+++ b/3party/boost/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 projections {
+
+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,@alaska,@ntv2_0.gsb,@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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUMS_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_ell_set.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_ell_set.hpp
new file mode 100644
index 0000000000..98f84917e1
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_ell_set.hpp
@@ -0,0 +1,157 @@
+// 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 projections {
+
+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)
+{
+ 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 {
+ int i = pj_param(parameters, "tR_lat_a").i;
+ if (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) > geometry::math::half_pi<double>()) {
+ 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELL_SET_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_ellps.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_ellps.hpp
new file mode 100644
index 0000000000..780db85a5b
--- /dev/null
+++ b/3party/boost/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 projections {
+
+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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELLPS_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_fwd.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_fwd.hpp
new file mode 100644
index 0000000000..06562b5d4d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_fwd.hpp
@@ -0,0 +1,99 @@
+// 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 <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/adjlon.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+#include <boost/math/constants/constants.hpp>
+
+/* general forward projection */
+
+namespace boost { namespace geometry { namespace projections {
+
+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) - geometry::math::half_pi<double>();
+
+ /* 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ }
+ 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_FWD_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_gauss.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_gauss.hpp
new file mode 100644
index 0000000000..c8fc8fd4c8
--- /dev/null
+++ b/3party/boost/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 projections {
+
+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) ) - geometry::math::half_pi<double>();
+
+ 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)) - geometry::math::half_pi<double>();
+
+ 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_GAUSS_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_init.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_init.hpp
new file mode 100644
index 0000000000..9234a6efa0
--- /dev/null
+++ b/3party/boost/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 projections
+{
+
+
+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>
+inline 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)
+{
+ 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_INIT_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_inv.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_inv.hpp
new file mode 100644
index 0000000000..dceabdf2be
--- /dev/null
+++ b/3party/boost/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 projections
+{
+
+namespace detail
+{
+
+namespace inv
+{
+ static const double EPS = 1.0e-12;
+}
+
+ /* inverse projection entry */
+template <typename PRJ, typename LL, typename XY, typename PAR>
+inline 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)-geometry::math::half_pi<double>()) > 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::projections
+
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp
new file mode 100644
index 0000000000..c4bbf266ef
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp
@@ -0,0 +1,112 @@
+// 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 projections {
+
+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 bool 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;
+ return true;
+}
+
+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::projections
+
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp
new file mode 100644
index 0000000000..80c86ef471
--- /dev/null
+++ b/3party/boost/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 projections {
+
+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::projections
+
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_param.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_param.hpp
new file mode 100644
index 0000000000..8e49ba46a6
--- /dev/null
+++ b/3party/boost/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 projections {
+
+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::projections
+
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp
new file mode 100644
index 0000000000..fec02240d5
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp
@@ -0,0 +1,71 @@
+// 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 projections {
+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 = geometry::math::half_pi<double>() - 2. * atan (ts);
+ i = phi2::N_ITER;
+ do {
+ con = e * sin (Phi);
+ dphi = geometry::math::half_pi<double>() - 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::projections
+
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp
new file mode 100644
index 0000000000..713802420f
--- /dev/null
+++ b/3party/boost/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 projections
+{ 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::projections
+
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp
new file mode 100644
index 0000000000..2e74e99aa1
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp
@@ -0,0 +1,53 @@
+// 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/util/math.hpp>
+
+namespace boost { namespace geometry { namespace projections {
+namespace detail {
+
+ /* determine small t */
+ inline double pj_tsfn(double phi, double sinphi, double e)
+ {
+ sinphi *= e;
+ return (tan (.5 * (geometry::math::half_pi<double>() - phi)) /
+ pow((1. - sinphi) / (1. + sinphi), .5 * e));
+ }
+
+} // namespace detail
+}}} // namespace boost::geometry::projections
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_units.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_units.hpp
new file mode 100644
index 0000000000..55f0252e74
--- /dev/null
+++ b/3party/boost/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 projections {
+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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_UNITS_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_zpoly1.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/pj_zpoly1.hpp
new file mode 100644
index 0000000000..af5708fd9b
--- /dev/null
+++ b/3party/boost/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 projections { 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::projections::detail
+
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/proj_mdist.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/proj_mdist.hpp
new file mode 100644
index 0000000000..9069b47b45
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/proj_mdist.hpp
@@ -0,0 +1,138 @@
+// 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 projections
+{
+namespace detail
+{
+ static const int MDIST_MAX_ITER = 20;
+
+ struct MDIST
+ {
+ int nb;
+ double es;
+ double E;
+ double b[MDIST_MAX_ITER];
+ };
+
+ inline bool 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.;
+ }
+ return true;
+ }
+ 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::projections
+
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/impl/projects.hpp b/3party/boost/boost/geometry/extensions/gis/projections/impl/projects.hpp
new file mode 100644
index 0000000000..7fbd5d8761
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/impl/projects.hpp
@@ -0,0 +1,181 @@
+// 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/math/constants/constants.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+/* some useful constants */
+static const double FORTPI = boost::math::constants::pi<double>() / 4.0;
+
+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)
+ : m_code(code)
+ {
+ }
+ int code() const { return m_code; }
+private :
+ int m_code;
+};
+
+}}} // namespace boost::geometry::projections
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PROJECTS_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/new_projection.hpp b/3party/boost/boost/geometry/extensions/gis/projections/new_projection.hpp
new file mode 100644
index 0000000000..f065297103
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/new_projection.hpp
@@ -0,0 +1,54 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2012 Krzysztof Czainski
+// 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)
+// 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)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_NEW_PROJECTION_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_NEW_PROJECTION_HPP
+
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/projection_point_type.hpp>
+#include <boost/geometry/extensions/gis/projections/projection.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+
+/*!
+\brief Creates a type-erased projection
+\details Creates using operator new a class derived from projection, that forwards method
+ calls to @p Proj.
+\ingroup projection
+\tparam Projection Type of the concrete projection to be created.
+\tparam Parameters projection parameters type
+\see projection
+\see factory
+*/
+
+//@{
+template <typename Projection, typename Parameters>
+inline projection
+ <
+ typename detail::projection_point_type<Projection, geographic_tag>::type
+ , typename detail::projection_point_type<Projection, cartesian_tag>::type
+ >* new_projection(Parameters const& par)
+{
+ return new detail::base_v_fi
+ <
+ Projection
+ , typename detail::projection_point_type<Projection, geographic_tag>::type
+ , typename detail::projection_point_type<Projection, cartesian_tag>::type
+ , Parameters
+ >(par);
+}
+//@}
+
+}}} // boost::geometry::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NEW_PROJECTION_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/parameters.hpp b/3party/boost/boost/geometry/extensions/gis/projections/parameters.hpp
new file mode 100644
index 0000000000..b41c0f5c63
--- /dev/null
+++ b/3party/boost/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 projections {
+
+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::projections
+#endif
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/aea.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/aea.hpp
new file mode 100644
index 0000000000..309dc66969
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/aea.hpp
@@ -0,0 +1,545 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the aea (Albers Equal Area) projection.
+// Author: Gerald Evenden
+// Copyright (c) 1995, Gerald Evenden
+
+// 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/core/ignore_unused.hpp>
+#include <boost/geometry/util/math.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>
+#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/epsg_traits.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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 phi1;
+ double phi2;
+ double en[EN_SIZE];
+ int ellips;
+ };
+
+ /* determine latitude angle phi-1 */
+ static 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;
+
+ 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) {}
+
+ // FORWARD(e_forward) ellipsoid & spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double rho = 0.0;
+ if ((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();
+ rho = this->m_proj_parm.dd * sqrt(rho);
+ xy_x = rho * sin( lp_lon *= this->m_proj_parm.n );
+ xy_y = this->m_proj_parm.rho0 - rho * cos(lp_lon);
+ }
+
+ // INVERSE(e_inverse) ellipsoid & spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double rho = 0.0;
+ 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;
+ }
+ lp_lat = 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ } 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n;
+ } else {
+ lp_lon = 0.;
+ lp_lat = this->m_proj_parm.n > 0. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>();
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "aea_ellipsoid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_aea& 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;
+
+ if (!pj_enfn(par.es, proj_parm.en)) throw proj_exception(0);
+ 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));
+ }
+ }
+
+
+ // Albers Equal Area
+ template <typename Parameters>
+ void setup_aea(Parameters& par, par_aea& proj_parm)
+ {
+ boost::ignore_unused(phi1_);
+ 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 ? - geometry::math::half_pi<double>(): geometry::math::half_pi<double>();
+ 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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ - lat_2: Latitude of second standard parallel (degrees)
+ \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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ - south: Denotes southern hemisphere UTM zone (boolean)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AEA_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/aeqd.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/aeqd.hpp
new file mode 100644
index 0000000000..55bcae3aa4
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/aeqd.hpp
@@ -0,0 +1,487 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the aeqd (Azimuthal Equidistant) projection.
+// Author: Gerald Evenden
+// Copyright (c) 1995, Gerald Evenden
+
+// 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/geometry/util/math.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/aasincos.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) elliptical
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+ }
+
+ // INVERSE(e_inverse) elliptical
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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 - geometry::math::half_pi<double>()) < 0.)
+ lp_lat = geometry::math::half_pi<double>();
+ 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);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "aeqd_ellipsoid";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(e_guam_fwd) Guam elliptical
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(e_guam_inv) Guam elliptical
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "aeqd_guam";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(s_forward) spherical
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 - geometry::math::half_pi<double>()) < EPS10) throw proj_exception();;
+ xy_x = (xy_y = (geometry::math::half_pi<double>() + lp_lat)) * sin(lp_lon);
+ xy_y *= coslam;
+ break;
+ }
+ }
+
+ // INVERSE(s_inverse) spherical
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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)) > geometry::math::pi<double>()) {
+ if (c_rh - EPS10 > geometry::math::pi<double>()) throw proj_exception();;
+ c_rh = geometry::math::pi<double>();
+ } 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 = atan2(xy_x, xy_y);
+ } else if (this->m_proj_parm.mode == N_POLE) {
+ lp_lat = geometry::math::half_pi<double>() - c_rh;
+ lp_lon = atan2(xy_x, -xy_y);
+ } else {
+ lp_lat = c_rh - geometry::math::half_pi<double>();
+ lp_lon = atan2(xy_x, xy_y);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "aeqd_spheroid";
+ }
+
+ };
+
+ // 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) - geometry::math::half_pi<double>()) < 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) {
+ } else {
+ if (!pj_enfn(par.es, proj_parm.en)) throw proj_exception(0);
+ if (pj_param(par.params, "bguam").i) {
+ proj_parm.M1 = pj_mlfn(par.phi0, proj_parm.sinph0, proj_parm.cosph0, proj_parm.en);
+ } else {
+ switch (proj_parm.mode) {
+ case N_POLE:
+ proj_parm.Mp = pj_mlfn(geometry::math::half_pi<double>(), 1., 0., proj_parm.en);
+ break;
+ case S_POLE:
+ proj_parm.Mp = pj_mlfn(-geometry::math::half_pi<double>(), -1., 0., proj_parm.en);
+ break;
+ case EQUIT:
+ case OBLIQ:
+ 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;
+ }
+ }
+ }
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_0: Latitude of origin (degrees)
+ - guam (boolean)
+ \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
+ \par Projection parameters
+ - lat_0: Latitude of origin (degrees)
+ - guam (boolean)
+ \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
+ \par Projection parameters
+ - lat_0: Latitude of origin (degrees)
+ - guam (boolean)
+ \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
+ {
+ bool const guam = pj_param(par.params, "bguam").i;
+
+ if (par.es && ! guam)
+ return new base_v_fi<aeqd_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else if (par.es && guam)
+ return new base_v_fi<aeqd_guam<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<aeqd_spheroid<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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/airy.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/airy.hpp
new file mode 100644
index 0000000000..d7396cab4e
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/airy.hpp
@@ -0,0 +1,231 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the airy (Airy) projection.
+// Author: Gerald Evenden
+// Copyright (c) 1995, Gerald Evenden
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) > geometry::math::half_pi<double>())
+ 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.;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "airy_spheroid";
+ }
+
+ };
+
+ // 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 * (geometry::math::half_pi<double>() - 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) - geometry::math::half_pi<double>()) < EPS)
+ if (par.phi0 < 0.) {
+ proj_parm.p_halfpi = -geometry::math::half_pi<double>();
+ proj_parm.mode = S_POLE;
+ } else {
+ proj_parm.p_halfpi = geometry::math::half_pi<double>();
+ 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.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
+ \par Projection parameters
+ - no_cut: Do not cut at hemisphere limit (boolean)
+ - lat_b (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/aitoff.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/aitoff.hpp
new file mode 100644
index 0000000000..f784f49db7
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/aitoff.hpp
@@ -0,0 +1,300 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the aitoff (Aitoff) and wintri (Winkel Tripel)
+// projections.
+// Author: Gerald Evenden
+// Copyright (c) 1995, Gerald Evenden
+
+// 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/core/ignore_unused.hpp>
+#include <boost/geometry/util/math.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 projections
+{
+ #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_fi<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_fi<base_aitoff_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+ }
+ /***********************************************************************************
+ *
+ * Inverse functions added by Drazen Tutic and Lovro Gradiser based on paper:
+ *
+ * I.Özbug Biklirici and Cengizhan Ipbüker. A General Algorithm for the Inverse
+ * Transformation of Map Projections Using Jacobian Matrices. In Proceedings of the
+ * Third International Symposium Mathematical & Computational Applications,
+ * pages 175{182, Turkey, September 2002.
+ *
+ * Expected accuracy is defined by EPSILON = 1e-12. Should be appropriate for
+ * most applications of Aitoff and Winkel Tripel projections.
+ *
+ * Longitudes of 180W and 180E can be mixed in solution obtained.
+ *
+ * Inverse for Aitoff projection in poles is undefined, longitude value of 0 is assumed.
+ *
+ * Contact : dtutic@geof.hr
+ * Date: 2015-02-16
+ *
+ ************************************************************************************/
+
+ // INVERSE(s_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ int iter, MAXITER = 10, round = 0, MAXROUND = 20;
+ double EPSILON = 1e-12, D, C, f1, f2, f1p, f1l, f2p, f2l, dp, dl, sl, sp, cp, cl, x, y;
+
+ if ((fabs(xy_x) < EPSILON) && (fabs(xy_y) < EPSILON )) { lp_lat = 0.; lp_lon = 0.; return; }
+
+ /* intial values for Newton-Raphson method */
+ lp_lat = xy_y; lp_lon = xy_x;
+ do {
+ iter = 0;
+ do {
+ sl = sin(lp_lon * 0.5); cl = cos(lp_lon * 0.5);
+ sp = sin(lp_lat); cp = cos(lp_lat);
+ D = cp * cl;
+ C = 1. - D * D;
+ D = acos(D) / pow(C, 1.5);
+ f1 = 2. * D * C * cp * sl;
+ f2 = D * C * sp;
+ f1p = 2.* (sl * cl * sp * cp / C - D * sp * sl);
+ f1l = cp * cp * sl * sl / C + D * cp * cl * sp * sp;
+ f2p = sp * sp * cl / C + D * sl * sl * cp;
+ f2l = 0.5 * (sp * cp * sl / C - D * sp * cp * cp * sl * cl);
+ if (this->m_proj_parm.mode) { /* Winkel Tripel */
+ f1 = 0.5 * (f1 + lp_lon * this->m_proj_parm.cosphi1);
+ f2 = 0.5 * (f2 + lp_lat);
+ f1p *= 0.5;
+ f1l = 0.5 * (f1l + this->m_proj_parm.cosphi1);
+ f2p = 0.5 * (f2p + 1.);
+ f2l *= 0.5;
+ }
+ f1 -= xy_x; f2 -= xy_y;
+ dl = (f2 * f1p - f1 * f2p) / (dp = f1p * f2l - f2p * f1l);
+ dp = (f1 * f2l - f2 * f1l) / dp;
+ while (dl > geometry::math::pi<double>()) dl -= geometry::math::pi<double>(); /* set to interval [-geometry::math::pi<double>(), geometry::math::pi<double>()] */
+ while (dl < -geometry::math::pi<double>()) dl += geometry::math::pi<double>(); /* set to interval [-geometry::math::pi<double>(), geometry::math::pi<double>()] */
+ lp_lat -= dp; lp_lon -= dl;
+ } while ((fabs(dp) > EPSILON || fabs(dl) > EPSILON) && (iter++ < MAXITER));
+ if (lp_lat > geometry::math::two_pi<double>()) lp_lat -= 2.*(lp_lat-geometry::math::two_pi<double>()); /* correct if symmetrical solution for Aitoff */
+ if (lp_lat < -geometry::math::two_pi<double>()) lp_lat -= 2.*(lp_lat+geometry::math::two_pi<double>()); /* correct if symmetrical solution for Aitoff */
+ if ((fabs(fabs(lp_lat) - geometry::math::two_pi<double>()) < EPSILON) && (!this->m_proj_parm.mode)) lp_lon = 0.; /* if pole in Aitoff, return longitude of 0 */
+
+ /* calculate x,y coordinates with solution obtained */
+ if((D = acos(cos(lp_lat) * cos(C = 0.5 * lp_lon)))) {/* Aitoff */
+ x = 2. * D * cos(lp_lat) * sin(C) * (y = 1. / sin(D));
+ y *= D * sin(lp_lat);
+ } else
+ x = y = 0.;
+ if (this->m_proj_parm.mode) { /* Winkel Tripel */
+ x = (x + lp_lon * this->m_proj_parm.cosphi1) * 0.5;
+ y = (y + lp_lat) * 0.5;
+ }
+ /* if too far from given values of x,y, repeat with better approximation of phi,lam */
+ } while (((fabs(xy_x-x) > EPSILON) || (fabs(xy_y-y) > EPSILON)) && (round++ < MAXROUND));
+
+ if (iter == MAXITER && round == MAXROUND) fprintf(stderr, "Warning: Accuracy of 1e-12 not reached. Last increments: dlat=%e and dlon=%e\n", dp, dl);
+ }
+
+ static inline std::string get_name()
+ {
+ return "aitoff_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_aitoff& proj_parm)
+ {
+ boost::ignore_unused(proj_parm);
+ 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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ \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_fi<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_fi<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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/august.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/august.hpp
new file mode 100644
index 0000000000..081729675d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/august.hpp
@@ -0,0 +1,148 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "august_spheroid";
+ }
+
+ };
+
+ // August Epicycloidal
+ template <typename Parameters>
+ void setup_august(Parameters& par)
+ {
+ 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/bacon.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/bacon.hpp
new file mode 100644
index 0000000000..b0d75dcab7
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/bacon.hpp
@@ -0,0 +1,247 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 ? geometry::math::half_pi<double>() * sin(lp_lat) : lp_lat;
+ if ((ax = fabs(lp_lon)) >= EPS) {
+ if (this->m_proj_parm.ortl && ax >= geometry::math::half_pi<double>())
+ xy_x = sqrt(HLFPI2 - lp_lat * lp_lat + EPS) + ax - geometry::math::half_pi<double>();
+ 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.;
+ }
+
+ static inline std::string get_name()
+ {
+ return "bacon_spheroid";
+ }
+
+ };
+
+ // 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.;
+ }
+
+ // 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.;
+ }
+
+ // 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.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BACON_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/bipc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/bipc.hpp
new file mode 100644
index 0000000000..97920f1a86
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/bipc.hpp
@@ -0,0 +1,268 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) < EPS10) {
+ Az = lp_lat < 0. ? geometry::math::pi<double>() : 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;
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "bipc_spheroid";
+ }
+
+ };
+
+ // 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.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 Projection parameters
+ - ns (boolean)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/boggs.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/boggs.hpp
new file mode 100644
index 0000000000..2c0593afca
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/boggs.hpp
@@ -0,0 +1,164 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) < EPS)
+ xy_x = 0.;
+ else {
+ c = sin(theta) * geometry::math::pi<double>();
+ 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "boggs_spheroid";
+ }
+
+ };
+
+ // Boggs Eumorphic
+ template <typename Parameters>
+ void setup_boggs(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/bonne.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/bonne.hpp
new file mode 100644
index 0000000000..387ee73f9c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/bonne.hpp
@@ -0,0 +1,270 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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)) < geometry::math::half_pi<double>()) {
+ 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 - geometry::math::half_pi<double>()) <= EPS10)
+ lp_lon = 0.;
+ else throw proj_exception();;
+ }
+
+ static inline std::string get_name()
+ {
+ return "bonne_ellipsoid";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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.;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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) > geometry::math::half_pi<double>()) throw proj_exception();;
+ if (fabs(fabs(lp_lat) - geometry::math::half_pi<double>()) <= EPS10)
+ lp_lon = 0.;
+ else
+ lp_lon = rh * atan2(xy_x, xy_y) / cos(lp_lat);
+ }
+
+ static inline std::string get_name()
+ {
+ return "bonne_spheroid";
+ }
+
+ };
+
+ // 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);
+ } else {
+ if (fabs(proj_parm.phi1) + EPS10 >= geometry::math::half_pi<double>())
+ proj_parm.cphi1 = 0.;
+ else
+ proj_parm.cphi1 = 1. / tan(proj_parm.phi1);
+ }
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ \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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/cass.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/cass.hpp
new file mode 100644
index 0000000000..f0a1c5a35e
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/cass.hpp
@@ -0,0 +1,477 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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 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;
+
+ 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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double n = sin(lp_lat);
+ double c = cos(lp_lat);
+ xy_y = pj_mlfn(lp_lat, n, c, this->m_proj_parm.en);
+ n = 1./sqrt(1. - this->m_par.es * n * n);
+ double tn = tan(lp_lat); double t = tn * tn;
+ double a1 = lp_lon * c;
+ c *= this->m_par.es * c / (1 - this->m_par.es);
+ double a2 = a1 * a1;
+ xy_x = n * a1 * (1. - a2 * t *
+ (C1 - (8. - t + 8. * c) * a2 * C2));
+ xy_y -= this->m_proj_parm.m0 - n * tn * a2 *
+ (.5 + (5. - t + 6. * c) * a2 * C3);
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ double tn = tan(ph1); double t = tn * tn;
+ double n = sin(ph1);
+ double r = 1. / (1. - this->m_par.es * n * n);
+ n = sqrt(r);
+ r *= (1. - this->m_par.es) * n;
+ double dd = xy_x / n;
+ double d2 = dd * dd;
+ lp_lat = ph1 - (n * tn / r) * d2 *
+ (.5 - (1. + 3. * t) * d2 * C3);
+ lp_lon = dd * (1. + t * d2 *
+ (-C4 + (1. + 3. * t) * d2 * C5)) / cos(ph1);
+ }
+
+ static inline std::string get_name()
+ {
+ return "cass_ellipsoid";
+ }
+
+ };
+
+ // 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;
+
+ 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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double dd = xy_y + this->m_par.phi0;
+ lp_lat = asin(sin(dd) * cos(xy_x));
+ lp_lon = atan2(tan(xy_x), cos(dd));
+ }
+
+ static inline std::string get_name()
+ {
+ return "cass_spheroid";
+ }
+
+ };
+
+ // Cassini
+ template <typename Parameters>
+ void setup_cass(Parameters& par, par_cass& proj_parm)
+ {
+ if (par.es) {
+ if (!pj_enfn(par.es, proj_parm.en)) throw proj_exception(0);
+ proj_parm.m0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en);
+ } else {
+ }
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CASS_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/cc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/cc.hpp
new file mode 100644
index 0000000000..f17c1b644c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/cc.hpp
@@ -0,0 +1,157 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) <= EPS10) throw proj_exception();;
+ xy_x = lp_lon;
+ xy_y = tan(lp_lat);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "cc_spheroid";
+ }
+
+ };
+
+ // Central Cylindrical
+ template <typename Parameters>
+ void setup_cc(Parameters& par, par_cc& proj_parm)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/cea.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/cea.hpp
new file mode 100644
index 0000000000..02037ba5d9
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/cea.hpp
@@ -0,0 +1,246 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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_auth.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(e_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "cea_ellipsoid";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ else
+ lp_lat = asin(xy_y);
+ lp_lon = xy_x / this->m_par.k0;
+ } else throw proj_exception();;
+ }
+
+ static inline std::string get_name()
+ {
+ return "cea_spheroid";
+ }
+
+ };
+
+ // Equal Area Cylindrical
+ template <typename Parameters>
+ void setup_cea(Parameters& par, par_cea& proj_parm)
+ {
+ double t = 0;
+
+ if (pj_param(par.params, "tlat_ts").i &&
+ (par.k0 = cos(t = pj_param(par.params, "rlat_ts").f)) < 0.)
+ throw proj_exception(-24);
+ if (par.es) {
+ t = sin(t);
+ par.k0 /= sqrt(1. - par.es * t * t);
+ par.e = sqrt(par.es);
+ if (!pj_authset(par.es, proj_parm.apa)) throw proj_exception(0);
+ proj_parm.qp = pj_qsfn(1., par.e, par.one_es);
+ } else {
+ }
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \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
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/chamb.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/chamb.hpp
new file mode 100644
index 0000000000..8b11fde28c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/chamb.hpp
@@ -0,0 +1,257 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.hpp>
+#include <cstdio>
+
+#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 projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace chamb
+ {
+
+ static const double THIRD = 0.333333333333333333;
+ static const double TOL = 1e-9;
+
+ // specific for 'chamb'
+ struct VECT { double r, Az; };
+ struct XY { double x, y; };
+
+ struct par_chamb
+ {
+ struct { /* control point data */
+ double phi, lam;
+ double cosphi, sinphi;
+ VECT v;
+ XY p;
+ double Az;
+ } c[3];
+ XY p;
+ double beta_0, beta_1, beta_2;
+ };
+
+ static 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;
+ }
+ static 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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "chamb_spheroid";
+ }
+
+ };
+
+ // 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 = geometry::math::pi<double>() - 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.;
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_1: Latitude of control point 1 (degrees)
+ - lon_1: Longitude of control point 1 (degrees)
+ - lat_2: Latitude of control point 2 (degrees)
+ - lon_2: Longitude of control point 2 (degrees)
+ - lat_3: Latitude of control point 3 (degrees)
+ - lon_3: Longitude of control point 3 (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/collg.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/collg.hpp
new file mode 100644
index 0000000000..0fabaa05b2
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/collg.hpp
@@ -0,0 +1,163 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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 - 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ if ((lp_lon = 1. - sin(lp_lat)) <= 0.)
+ lp_lon = 0.;
+ else
+ lp_lon = xy_x / (FXC * sqrt(lp_lon));
+ }
+
+ static inline std::string get_name()
+ {
+ return "collg_spheroid";
+ }
+
+ };
+
+ // Collignon
+ template <typename Parameters>
+ void setup_collg(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/crast.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/crast.hpp
new file mode 100644
index 0000000000..6298e8d87c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/crast.hpp
@@ -0,0 +1,153 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "crast_spheroid";
+ }
+
+ };
+
+ // Craster Parabolic (Putnins P4)
+ template <typename Parameters>
+ void setup_crast(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/denoy.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/denoy.hpp
new file mode 100644
index 0000000000..e50195151b
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/denoy.hpp
@@ -0,0 +1,148 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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)));
+ }
+
+ static inline std::string get_name()
+ {
+ return "denoy_spheroid";
+ }
+
+ };
+
+ // Denoyer Semi-Elliptical
+ template <typename Parameters>
+ void setup_denoy(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/eck1.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/eck1.hpp
new file mode 100644
index 0000000000..8ab1ee891d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/eck1.hpp
@@ -0,0 +1,149 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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)));
+ }
+
+ static inline std::string get_name()
+ {
+ return "eck1_spheroid";
+ }
+
+ };
+
+ // Eckert I
+ template <typename Parameters>
+ void setup_eck1(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/eck2.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/eck2.hpp
new file mode 100644
index 0000000000..12146f741b
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/eck2.hpp
@@ -0,0 +1,162 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ } else
+ lp_lat = asin(lp_lat);
+ if (xy_y < 0)
+ lp_lat = -lp_lat;
+ }
+
+ static inline std::string get_name()
+ {
+ return "eck2_spheroid";
+ }
+
+ };
+
+ // Eckert II
+ template <typename Parameters>
+ void setup_eck2(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/eck3.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/eck3.hpp
new file mode 100644
index 0000000000..c336d713bc
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/eck3.hpp
@@ -0,0 +1,296 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/core/ignore_unused.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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));
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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)));
+ }
+
+ static inline std::string get_name()
+ {
+ return "eck3_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_eck3& proj_parm)
+ {
+ boost::ignore_unused(proj_parm);
+ par.es = 0.;
+ }
+
+
+ // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/eck4.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/eck4.hpp
new file mode 100644
index 0000000000..b3cd36b0b5
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/eck4.hpp
@@ -0,0 +1,177 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "eck4_spheroid";
+ }
+
+ };
+
+ // Eckert IV
+ template <typename Parameters>
+ void setup_eck4(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/eck5.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/eck5.hpp
new file mode 100644
index 0000000000..c52d98cbce
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/eck5.hpp
@@ -0,0 +1,150 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "eck5_spheroid";
+ }
+
+ };
+
+ // Eckert V
+ template <typename Parameters>
+ void setup_eck5(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/eqc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/eqc.hpp
new file mode 100644
index 0000000000..f758b7f037
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/eqc.hpp
@@ -0,0 +1,156 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "eqc_spheroid";
+ }
+
+ };
+
+ // 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.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
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ - lat_0: Latitude of origin
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_EQC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/eqdc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/eqdc.hpp
new file mode 100644
index 0000000000..8da653a676
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/eqdc.hpp
@@ -0,0 +1,230 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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>
+#include <boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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 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;
+
+ 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) {}
+
+ // FORWARD(e_forward) sphere & ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double rho = 0.0;
+ 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 = rho * sin( lp_lon *= this->m_proj_parm.n );
+ xy_y = this->m_proj_parm.rho0 - rho * cos(lp_lon);
+ }
+
+ // INVERSE(e_inverse) sphere & ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double rho = 0.0;
+ 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;
+ }
+ lp_lat = this->m_proj_parm.c - 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. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>();
+ }
+ }
+
+ // SPECIAL(fac)
+ #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
+
+ static inline std::string get_name()
+ {
+ return "eqdc_ellipsoid";
+ }
+
+ };
+
+ // 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);
+ if (!pj_enfn(par.es, proj_parm.en))
+ throw proj_exception(0);
+ 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;
+ }
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ - lat_2: Latitude of second standard parallel (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/etmerc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/etmerc.hpp
new file mode 100644
index 0000000000..16fbcc854c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/etmerc.hpp
@@ -0,0 +1,370 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Copyright (c) 2008 Gerald I. Evenden
+
+// 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 projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace etmerc
+ {
+
+ static const int PROJ_ETMERC_ORDER = 6;
+
+ struct par_etmerc
+ {
+ double Qn; /* Merid. quad., scaled to the projection */
+ double Zb; /* Radius vector in polar coord. systems */
+ double cgb[6]; /* Constants for Gauss -> Geo lat */
+ double cbg[6]; /* Constants for Geo lat -> Gauss */
+ double utg[6]; /* Constants for transv. merc. -> geo */
+ double gtu[6]; /* Constants for geo -> transv. merc. */
+ };
+
+ /* The code in this file is largly based upon procedures:
+ *
+ * Written by: Knud Poder and Karsten Engsager
+ *
+ * Based on math from: R.Koenig and K.H. Weise, "Mathematische
+ * Grundlagen der hoeheren Geodaesie und Kartographie,
+ * Springer-Verlag, Berlin/Goettingen" Heidelberg, 1951.
+ *
+ * Modified and used here by permission of Reference Networks
+ * Division, Kort og Matrikelstyrelsen (KMS), Copenhagen, Denmark
+ */
+
+
+
+
+
+
+ static double
+ log1py(double x) { /* Compute log(1+x) accurately */
+ volatile double
+ y = 1 + x,
+ z = y - 1;
+ /* Here's the explanation for this magic: y = 1 + z, exactly, and z
+ * approx x, thus log(y)/z (which is nearly constant near z = 0) returns
+ * a good approximation to the true log(1 + x)/x. The multiplication x *
+ * (log(y)/z) introduces little additional error. */
+ return z == 0 ? x : x * log(y) / z;
+ }
+
+ static double
+ asinhy(double x) { /* Compute asinh(x) accurately */
+ double y = fabs(x); /* Enforce odd parity */
+ y = log1py(y * (1 + y/(boost::math::hypot(1.0, y) + 1)));
+ return x < 0 ? -y : y;
+ }
+
+ static double
+ gatg(const double *p1, int len_p1, double B) {
+ const double *p;
+ double h = 0, h1, h2 = 0, cos_2B;
+
+ cos_2B = 2*cos(2*B);
+ for (p = p1 + len_p1, h1 = *--p; p - p1; h2 = h1, h1 = h)
+ h = -h2 + cos_2B*h1 + *--p;
+ return (B + h*sin(2*B));
+ }
+
+ static double
+ clenS(const double *a, int size, double arg_r, double arg_i, double *R, double *I) {
+ double r, i, hr, hr1, hr2, hi, hi1, hi2;
+ double sin_arg_r, cos_arg_r, sinh_arg_i, cosh_arg_i;
+
+ /* arguments */
+ const double* p = a + size;
+ sin_arg_r = sin(arg_r);
+ cos_arg_r = cos(arg_r);
+ sinh_arg_i = sinh(arg_i);
+ cosh_arg_i = cosh(arg_i);
+ r = 2*cos_arg_r*cosh_arg_i;
+ i = -2*sin_arg_r*sinh_arg_i;
+ /* summation loop */
+ for (hi1 = hr1 = hi = 0, hr = *--p; a - p;) {
+ hr2 = hr1;
+ hi2 = hi1;
+ hr1 = hr;
+ hi1 = hi;
+ hr = -hr2 + r*hr1 - i*hi1 + *--p;
+ hi = -hi2 + i*hr1 + r*hi1;
+ }
+ r = sin_arg_r*cosh_arg_i;
+ i = cos_arg_r*sinh_arg_i;
+ *R = r*hr - i*hi;
+ *I = r*hi + i*hr;
+ return(*R);
+ }
+ static double
+ clens(const double *a, int size, double arg_r) {
+ double r, hr, hr1, hr2, cos_arg_r;
+
+ const double* p = a + size;
+ cos_arg_r = cos(arg_r);
+ r = 2*cos_arg_r;
+ /* summation loop */
+ for (hr1 = 0, hr = *--p; a - p;) {
+ hr2 = hr1;
+ hr1 = hr;
+ hr = -hr2 + r*hr1 + *--p;
+ }
+ return(sin(arg_r)*hr);
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_etmerc_ellipsoid : public base_t_fi<base_etmerc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_etmerc m_proj_parm;
+
+ inline base_etmerc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_etmerc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double sin_Cn, cos_Cn, cos_Ce, sin_Ce, dCn, dCe;
+ double Cn = lp_lat, Ce = lp_lon;
+
+ /* ell. LAT, LNG -> Gaussian LAT, LNG */
+ Cn = gatg(this->m_proj_parm.cbg, PROJ_ETMERC_ORDER, Cn);
+ /* Gaussian LAT, LNG -> compl. sph. LAT */
+ sin_Cn = sin(Cn);
+ cos_Cn = cos(Cn);
+ sin_Ce = sin(Ce);
+ cos_Ce = cos(Ce);
+
+ Cn = atan2(sin_Cn, cos_Ce*cos_Cn);
+ Ce = atan2(sin_Ce*cos_Cn, boost::math::hypot(sin_Cn, cos_Cn*cos_Ce));
+ /* compl. sph. N, E -> ell. norm. N, E */
+ Ce = asinhy(tan(Ce)); /* Replaces: Ce = log(tan(FORTPI + Ce*0.5)); */
+ Cn += clenS(this->m_proj_parm.gtu, PROJ_ETMERC_ORDER, 2*Cn, 2*Ce, &dCn, &dCe);
+ Ce += dCe;
+ if (fabs(Ce) <= 2.623395162778) {
+ xy_y = this->m_proj_parm.Qn * Cn + this->m_proj_parm.Zb; /* Northing */
+ xy_x = this->m_proj_parm.Qn * Ce; /* Easting */
+ } else
+ xy_x = xy_y = HUGE_VAL;
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double sin_Cn, cos_Cn, cos_Ce, sin_Ce, dCn, dCe;
+ double Cn = xy_y, Ce = xy_x;
+
+ /* normalize N, E */
+ Cn = (Cn - this->m_proj_parm.Zb)/this->m_proj_parm.Qn;
+ Ce = Ce/this->m_proj_parm.Qn;
+ if (fabs(Ce) <= 2.623395162778) { /* 150 degrees */
+ /* norm. N, E -> compl. sph. LAT, LNG */
+ Cn += clenS(this->m_proj_parm.utg, PROJ_ETMERC_ORDER, 2*Cn, 2*Ce, &dCn, &dCe);
+ Ce += dCe;
+ Ce = atan(sinh(Ce)); /* Replaces: Ce = 2*(atan(exp(Ce)) - FORTPI); */
+ /* compl. sph. LAT -> Gaussian LAT, LNG */
+ sin_Cn = sin(Cn);
+ cos_Cn = cos(Cn);
+ sin_Ce = sin(Ce);
+ cos_Ce = cos(Ce);
+ Ce = atan2(sin_Ce, cos_Ce*cos_Cn);
+ Cn = atan2(sin_Cn*cos_Ce, boost::math::hypot(sin_Ce, cos_Ce*cos_Cn));
+ /* Gaussian LAT, LNG -> ell. LAT, LNG */
+ lp_lat = gatg(this->m_proj_parm.cgb, PROJ_ETMERC_ORDER, Cn);
+ lp_lon = Ce;
+ }
+ else
+ lp_lat = lp_lon = HUGE_VAL;
+ }
+
+ static inline std::string get_name()
+ {
+ return "etmerc_ellipsoid";
+ }
+
+ };
+
+ // Extended Transverse Mercator
+ template <typename Parameters>
+ void setup_etmerc(Parameters& par, par_etmerc& proj_parm)
+ {
+ double f, n, np, Z;
+
+ if (par.es <= 0) throw proj_exception(-34);
+ f = par.es / (1 + sqrt(1 - par.es)); /* Replaces: f = 1 - sqrt(1-par.es); */
+ /* third flattening */
+ np = n = f/(2 - f);
+
+ /* COEF. OF TRIG SERIES GEO <-> GAUSS */
+ /* cgb := Gaussian -> Geodetic, KW p190 - 191 (61) - (62) */
+ /* cbg := Geodetic -> Gaussian, KW p186 - 187 (51) - (52) */
+ /* PROJ_ETMERC_ORDER = 6th degree : Engsager and Poder: ICC2007 */
+ proj_parm.cgb[0] = n*( 2 + n*(-2/3.0 + n*(-2 + n*(116/45.0 + n*(26/45.0 +
+ n*(-2854/675.0 ))))));
+ proj_parm.cbg[0] = n*(-2 + n*( 2/3.0 + n*( 4/3.0 + n*(-82/45.0 + n*(32/45.0 +
+ n*( 4642/4725.0))))));
+ np *= n;
+ proj_parm.cgb[1] = np*(7/3.0 + n*( -8/5.0 + n*(-227/45.0 + n*(2704/315.0 +
+ n*( 2323/945.0)))));
+ proj_parm.cbg[1] = np*(5/3.0 + n*(-16/15.0 + n*( -13/9.0 + n*( 904/315.0 +
+ n*(-1522/945.0)))));
+ np *= n;
+ /* n^5 coeff corrected from 1262/105 -> -1262/105 */
+ proj_parm.cgb[2] = np*( 56/15.0 + n*(-136/35.0 + n*(-1262/105.0 +
+ n*( 73814/2835.0))));
+ proj_parm.cbg[2] = np*(-26/15.0 + n*( 34/21.0 + n*( 8/5.0 +
+ n*(-12686/2835.0))));
+ np *= n;
+ /* n^5 coeff corrected from 322/35 -> 332/35 */
+ proj_parm.cgb[3] = np*(4279/630.0 + n*(-332/35.0 + n*(-399572/14175.0)));
+ proj_parm.cbg[3] = np*(1237/630.0 + n*( -12/5.0 + n*( -24832/14175.0)));
+ np *= n;
+ proj_parm.cgb[4] = np*(4174/315.0 + n*(-144838/6237.0 ));
+ proj_parm.cbg[4] = np*(-734/315.0 + n*( 109598/31185.0));
+ np *= n;
+ proj_parm.cgb[5] = np*(601676/22275.0 );
+ proj_parm.cbg[5] = np*(444337/155925.0);
+
+ /* Constants of the projections */
+ /* Transverse Mercator (UTM, ITM, etc) */
+ np = n*n;
+ /* Norm. mer. quad, K&W p.50 (96), p.19 (38b), p.5 (2) */
+ proj_parm.Qn = par.k0/(1 + n) * (1 + np*(1/4.0 + np*(1/64.0 + np/256.0)));
+ /* coef of trig series */
+ /* utg := ell. N, E -> sph. N, E, KW p194 (65) */
+ /* gtu := sph. N, E -> ell. N, E, KW p196 (69) */
+ proj_parm.utg[0] = n*(-0.5 + n*( 2/3.0 + n*(-37/96.0 + n*( 1/360.0 +
+ n*( 81/512.0 + n*(-96199/604800.0))))));
+ proj_parm.gtu[0] = n*( 0.5 + n*(-2/3.0 + n*( 5/16.0 + n*(41/180.0 +
+ n*(-127/288.0 + n*( 7891/37800.0 ))))));
+ proj_parm.utg[1] = np*(-1/48.0 + n*(-1/15.0 + n*(437/1440.0 + n*(-46/105.0 +
+ n*( 1118711/3870720.0)))));
+ proj_parm.gtu[1] = np*(13/48.0 + n*(-3/5.0 + n*(557/1440.0 + n*(281/630.0 +
+ n*(-1983433/1935360.0)))));
+ np *= n;
+ proj_parm.utg[2] = np*(-17/480.0 + n*( 37/840.0 + n*( 209/4480.0 +
+ n*( -5569/90720.0 ))));
+ proj_parm.gtu[2] = np*( 61/240.0 + n*(-103/140.0 + n*(15061/26880.0 +
+ n*(167603/181440.0))));
+ np *= n;
+ proj_parm.utg[3] = np*(-4397/161280.0 + n*( 11/504.0 + n*( 830251/7257600.0)));
+ proj_parm.gtu[3] = np*(49561/161280.0 + n*(-179/168.0 + n*(6601661/7257600.0)));
+ np *= n;
+ proj_parm.utg[4] = np*(-4583/161280.0 + n*( 108847/3991680.0));
+ proj_parm.gtu[4] = np*(34729/80640.0 + n*(-3418889/1995840.0));
+ np *= n;
+ proj_parm.utg[5] = np*(-20648693/638668800.0);
+ proj_parm.gtu[5] = np*(212378941/319334400.0);
+ /* Gaussian latitude value of the origin latitude */
+ Z = gatg(proj_parm.cbg, PROJ_ETMERC_ORDER, par.phi0);
+ /* Origin northing minus true northing at the origin latitude */
+ /* i.e. true northing = N - proj_parm.Zb */
+ proj_parm.Zb = - proj_parm.Qn*(Z + clens(proj_parm.gtu, PROJ_ETMERC_ORDER, 2*Z));
+ }
+
+ }} // namespace detail::etmerc
+ #endif // doxygen
+
+ /*!
+ \brief Extended Transverse Mercator projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Projection parameters
+ - lat_ts: Latitude of true scale
+ - lat_0: Latitude of origin
+ \par Example
+ \image html ex_etmerc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct etmerc_ellipsoid : public detail::etmerc::base_etmerc_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline etmerc_ellipsoid(const Parameters& par) : detail::etmerc::base_etmerc_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::etmerc::setup_etmerc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class etmerc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<etmerc_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void etmerc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("etmerc", new etmerc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/fahey.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/fahey.hpp
new file mode 100644
index 0000000000..fb1c86a3c1
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/fahey.hpp
@@ -0,0 +1,150 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "fahey_spheroid";
+ }
+
+ };
+
+ // Fahey
+ template <typename Parameters>
+ void setup_fahey(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/fouc_s.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/fouc_s.hpp
new file mode 100644
index 0000000000..e2452b58e7
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/fouc_s.hpp
@@ -0,0 +1,182 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ } 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "fouc_s_spheroid";
+ }
+
+ };
+
+ // 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;
+ }
+
+ }} // 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 Projection parameters
+ - n (real)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/gall.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/gall.hpp
new file mode 100644
index 0000000000..425f4a2f29
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/gall.hpp
@@ -0,0 +1,151 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "gall_spheroid";
+ }
+
+ };
+
+ // Gall (Gall Stereographic)
+ template <typename Parameters>
+ void setup_gall(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GALL_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/geocent.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/geocent.hpp
new file mode 100644
index 0000000000..8c7469d3af
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/geocent.hpp
@@ -0,0 +1,151 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Stub projection for geocentric. The transformation isn't
+// really done here since this code is 2D. The real transformation
+// is handled by pj_transform.c.
+// Author: Frank Warmerdam, warmerdam@pobox.com
+// Copyright (c) 2002, Frank Warmerdam
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(forward)
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(inverse)
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "geocent_other";
+ }
+
+ };
+
+ // Geocentric
+ template <typename Parameters>
+ void setup_geocent(Parameters& par)
+ {
+ par.is_geocent = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ }
+
+ }} // 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 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/geos.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/geos.hpp
new file mode 100644
index 0000000000..375998b63c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/geos.hpp
@@ -0,0 +1,355 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Copyright (c) 2004 Gerald I. Evenden
+// Copyright (c) 2012 Martin Raspaud
+// See also (section 4.4.3.2):
+// http://www.eumetsat.int/en/area4/msg/news/us_doc/cgms_03_26.pdf
+
+// 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 projections
+{
+ #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;
+ std::string sweep_axis;
+ int flip_axis;
+ };
+
+ // 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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ if(this->m_proj_parm.flip_axis)
+ {
+ xy_x = this->m_proj_parm.radius_g_1 * atan (Vy / boost::math::hypot (Vz, tmp));
+ xy_y = this->m_proj_parm.radius_g_1 * atan (Vz / tmp);
+ }
+ else
+ {
+ 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));
+ }
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ if(this->m_proj_parm.flip_axis)
+ {
+ Vz = tan (xy_y / this->m_proj_parm.radius_g_1);
+ Vy = tan (xy_x / this->m_proj_parm.radius_g_1) * boost::math::hypot(1.0, Vz);
+ }
+ else
+ {
+ 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "geos_ellipsoid";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ if(this->m_proj_parm.flip_axis)
+ {
+ xy_x = this->m_proj_parm.radius_g_1 * atan(Vy / boost::math::hypot(Vz, tmp));
+ xy_y = this->m_proj_parm.radius_g_1 * atan(Vz / tmp);
+ }
+ else
+ {
+ 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));
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ if(this->m_proj_parm.flip_axis)
+ {
+ Vz = tan (xy_y / (this->m_proj_parm.radius_g - 1.0));
+ Vy = tan (xy_x / (this->m_proj_parm.radius_g - 1.0)) * sqrt (1.0 + Vz * Vz);
+ }
+ else
+ {
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "geos_spheroid";
+ }
+
+ };
+
+ // 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.sweep_axis = pj_param(par.params, "ssweep").s;
+ if (proj_parm.sweep_axis.empty())
+ proj_parm.flip_axis = 0;
+ else
+ {
+ if (proj_parm.sweep_axis[1] != '\0' ||
+ (proj_parm.sweep_axis[0] != 'x' &&
+ proj_parm.sweep_axis[0] != 'y'))
+ throw proj_exception(-49);
+ if (proj_parm.sweep_axis[0] == 'x')
+ proj_parm.flip_axis = 1;
+ else
+ proj_parm.flip_axis = 0;
+ }
+ proj_parm.radius_g_1 = proj_parm.h / par.a;
+ proj_parm.radius_g = 1. + proj_parm.radius_g_1;
+ 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;
+ } else {
+ proj_parm.radius_p = proj_parm.radius_p2 = proj_parm.radius_p_inv2 = 1.0;
+ }
+ }
+
+ }} // 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
+ \par Projection parameters
+ - h: Height (real)
+ - sweep: Sweep axis ('x' or 'y') (string)
+ \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
+ \par Projection parameters
+ - h: Height (real)
+ - sweep: Sweep axis ('x' or 'y') (string)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/gins8.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/gins8.hpp
new file mode 100644
index 0000000000..96de4cb90d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/gins8.hpp
@@ -0,0 +1,147 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "gins8_spheroid";
+ }
+
+ };
+
+ // Ginsburg VIII (TsNIIGAiK)
+ template <typename Parameters>
+ void setup_gins8(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/gn_sinu.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/gn_sinu.hpp
new file mode 100644
index 0000000000..dc585bd5b0
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/gn_sinu.hpp
@@ -0,0 +1,398 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double s;
+
+ if ((s = fabs(lp_lat = pj_inv_mlfn(xy_y, this->m_par.es, this->m_proj_parm.en))) < geometry::math::half_pi<double>()) {
+ s = sin(lp_lat);
+ lp_lon = xy_x * sqrt(1. - this->m_par.es * s * s) / cos(lp_lat);
+ } else if ((s - EPS10) < geometry::math::half_pi<double>())
+ lp_lon = 0.;
+ else throw proj_exception();;
+ }
+ /* General spherical sinusoidals */
+
+ static inline std::string get_name()
+ {
+ return "gn_sinu_ellipsoid";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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 = 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)));
+ }
+
+ static inline std::string get_name()
+ {
+ return "gn_sinu_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_gn_sinu& 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.);
+ }
+
+
+ // 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)
+ {
+ if (!pj_enfn(par.es, proj_parm.en))
+ throw proj_exception(0);
+ if (par.es) {
+ } 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 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
+ \par Projection parameters
+ - m (real)
+ - n (real)
+ \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_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 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/gnom.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/gnom.hpp
new file mode 100644
index 0000000000..ea771b2721
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/gnom.hpp
@@ -0,0 +1,240 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>();
+ 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. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>();
+ else
+ lp_lat = asin(lp_lat);
+ xy_y = cosz * rh;
+ xy_x *= sinz;
+ break;
+ case S_POLE:
+ lp_lat -= geometry::math::half_pi<double>();
+ break;
+ case N_POLE:
+ lp_lat = geometry::math::half_pi<double>() - lp_lat;
+ xy_y = -xy_y;
+ break;
+ }
+ lp_lon = atan2(xy_x, xy_y);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "gnom_spheroid";
+ }
+
+ };
+
+ // Gnomonic
+ template <typename Parameters>
+ void setup_gnom(Parameters& par, par_gnom& proj_parm)
+ {
+ if (fabs(fabs(par.phi0) - geometry::math::half_pi<double>()) < 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.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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/goode.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/goode.hpp
new file mode 100644
index 0000000000..9ce3ee78c5
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/goode.hpp
@@ -0,0 +1,169 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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/gn_sinu.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/moll.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "goode_spheroid";
+ }
+
+ };
+
+ // Goode Homolosine
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ void setup_goode(Parameters& par, par_goode<Geographic, Cartesian, Parameters>& proj_parm)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/gstmerc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/gstmerc.hpp
new file mode 100644
index 0000000000..b73ef80a22
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/gstmerc.hpp
@@ -0,0 +1,184 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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_phi2.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);*/
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);*/
+ }
+
+ static inline std::string get_name()
+ {
+ return "gstmerc_spheroid";
+ }
+
+ };
+
+ // 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 */
+ /*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
+ \par Projection parameters
+ - lat_0: Latitude of origin
+ - lon_0: Central meridian
+ - k_0: Scale factor
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/hammer.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/hammer.hpp
new file mode 100644
index 0000000000..aa61e771d5
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/hammer.hpp
@@ -0,0 +1,162 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "hammer_spheroid";
+ }
+
+ };
+
+ // 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.;
+ }
+
+ }} // 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
+ \par Projection parameters
+ - W (real)
+ - M (real)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/hatano.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/hatano.hpp
new file mode 100644
index 0000000000..3c66259335
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/hatano.hpp
@@ -0,0 +1,184 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>();
+ 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. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>();
+ else
+ lp_lat = asin(lp_lat);
+ }
+
+ static inline std::string get_name()
+ {
+ return "hatano_spheroid";
+ }
+
+ };
+
+ // Hatano Asymmetrical Equal Area
+ template <typename Parameters>
+ void setup_hatano(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/healpix.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/healpix.hpp
new file mode 100644
index 0000000000..eb96abb30b
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/healpix.hpp
@@ -0,0 +1,846 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the HEALPix and rHEALPix projections.
+// For background see <http://code.scenzgrid.org/index.php/p/scenzgrid-py/source/tree/master/docs/rhealpix_dggs.pdf>.
+// Authors: Alex Raichev (raichev@cs.auckland.ac.nz)
+// Michael Speth (spethm@landcareresearch.co.nz)
+// Notes: Raichev implemented these projections in Python and
+// Speth translated them into C here.
+// Copyright (c) 2001, Thomas Flemming, tf@ttqv.com
+
+// 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/geometry/util/math.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_auth.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace healpix
+ {
+
+ static const double EPS = 1e-15;
+
+ struct par_healpix
+ {
+ int north_square;
+ int south_square;
+ double qp;
+ double apa[APA_SIZE];
+ };
+
+ /* Matrix for counterclockwise rotation by pi/2: */
+ /* Matrix for counterclockwise rotation by pi: */
+ /* Matrix for counterclockwise rotation by 3*pi/2: */
+ /* Identity matrix */
+ /* IDENT, R1, R2, R3, R1 inverse, R2 inverse, R3 inverse:*/
+ /* Fuzz to handle rounding errors: */
+ typedef struct {
+ int cn; /* An integer 0--3 indicating the position of the polar cap. */
+ double x, y; /* Coordinates of the pole point (point of most extreme latitude on the polar caps). */
+ enum Region {north, south, equatorial} region;
+ } CapMap;
+ typedef struct {
+ double x, y;
+ } Point;
+ double rot[7][2][2] = {{{1, 0},{0, 1}}, {{ 0,-1},{ 1, 0}}, {{-1, 0},{ 0,-1}}, {{ 0, 1},{-1, 0}}, {{ 0, 1},{-1, 0}}, {{-1, 0},{ 0,-1}}, {{ 0,-1},{ 1, 0}}};
+
+ /**
+ * Returns the sign of the double.
+ * @param v the parameter whose sign is returned.
+ * @return 1 for positive number, -1 for negative, and 0 for zero.
+ **/
+ double pj_sign (double v) {
+ return v > 0 ? 1 : (v < 0 ? -1 : 0);
+ }
+ /**
+ * Return the index of the matrix in {{{1, 0},{0, 1}}, {{ 0,-1},{ 1, 0}}, {{-1, 0},{ 0,-1}}, {{ 0, 1},{-1, 0}}, {{ 0, 1},{-1, 0}}, {{-1, 0},{ 0,-1}}, {{ 0,-1},{ 1, 0}}}.
+ * @param index ranges from -3 to 3.
+ */
+ static int get_rotate_index(int index) {
+ switch(index) {
+ case 0:
+ return 0;
+ case 1:
+ return 1;
+ case 2:
+ return 2;
+ case 3:
+ return 3;
+ case -1:
+ return 4;
+ case -2:
+ return 5;
+ case -3:
+ return 6;
+ }
+ return 0;
+ }
+ /**
+ * Return 1 if point (testx, testy) lies in the interior of the polygon
+ * determined by the vertices in vert, and return 0 otherwise.
+ * See http://paulbourke.net/geometry/polygonmesh/ for more details.
+ * @param nvert the number of vertices in the polygon.
+ * @param vert the (x, y)-coordinates of the polygon's vertices
+ **/
+ static int pnpoly(int nvert, double vert[][2], double testx, double testy) {
+ int i, c = 0;
+ int counter = 0;
+ double xinters;
+ Point p1, p2;
+ /* Check for boundrary cases */
+ for (i = 0; i < nvert; i++) {
+ if (testx == vert[i][0] && testy == vert[i][1]) {
+ return 1;
+ }
+ }
+ p1.x = vert[0][0];
+ p1.y = vert[0][1];
+ for (i = 1; i < nvert; i++) {
+ p2.x = vert[i % nvert][0];
+ p2.y = vert[i % nvert][1];
+ if (testy > (std::min)(p1.y, p2.y)) {
+ if (testy <= (std::max)(p1.y, p2.y)) {
+ if (testx <= (std::max)(p1.x, p2.x)) {
+ if (p1.y != p2.y) {
+ xinters = (testy-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
+ if (p1.x == p2.x || testx <= xinters) {
+ counter++;
+ }
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+ if (counter % 2 == 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+ return c;
+ }
+ /**
+ * Return 1 if (x, y) lies in (the interior or boundary of) the image of the
+ * HEALPix projection (in case proj=0) or in the image the rHEALPix projection
+ * (in case proj=1), and return 0 otherwise.
+ * @param north_square the position of the north polar square (rHEALPix only)
+ * @param south_square the position of the south polar square (rHEALPix only)
+ **/
+ int in_image(double x, double y, int proj, int north_square, int south_square) {
+ if (proj == 0) {
+ double healpixVertsJit[][2] = {
+ {-1.0*geometry::math::pi<double>()- EPS, geometry::math::pi<double>()/4.0},
+ {-3.0*geometry::math::pi<double>()/4.0, geometry::math::pi<double>()/2.0 + EPS},
+ {-1.0*geometry::math::pi<double>()/2.0, geometry::math::pi<double>()/4.0 + EPS},
+ {-1.0*geometry::math::pi<double>()/4.0, geometry::math::pi<double>()/2.0 + EPS},
+ {0.0, geometry::math::pi<double>()/4.0 + EPS},
+ {geometry::math::pi<double>()/4.0, geometry::math::pi<double>()/2.0 + EPS},
+ {geometry::math::pi<double>()/2.0, geometry::math::pi<double>()/4.0 + EPS},
+ {3.0*geometry::math::pi<double>()/4.0, geometry::math::pi<double>()/2.0 + EPS},
+ {geometry::math::pi<double>()+ EPS, geometry::math::pi<double>()/4.0},
+ {geometry::math::pi<double>()+ EPS, -1.0*geometry::math::pi<double>()/4.0},
+ {3.0*geometry::math::pi<double>()/4.0, -1.0*geometry::math::pi<double>()/2.0 - EPS},
+ {geometry::math::pi<double>()/2.0, -1.0*geometry::math::pi<double>()/4.0 - EPS},
+ {geometry::math::pi<double>()/4.0, -1.0*geometry::math::pi<double>()/2.0 - EPS},
+ {0.0, -1.0*geometry::math::pi<double>()/4.0 - EPS},
+ {-1.0*geometry::math::pi<double>()/4.0, -1.0*geometry::math::pi<double>()/2.0 - EPS},
+ {-1.0*geometry::math::pi<double>()/2.0, -1.0*geometry::math::pi<double>()/4.0 - EPS},
+ {-3.0*geometry::math::pi<double>()/4.0, -1.0*geometry::math::pi<double>()/2.0 - EPS},
+ {-1.0*geometry::math::pi<double>() - EPS, -1.0*geometry::math::pi<double>()/4.0}
+ };
+ return pnpoly((int)sizeof(healpixVertsJit)/
+ sizeof(healpixVertsJit[0]), healpixVertsJit, x, y);
+ } else {
+ double rhealpixVertsJit[][2] = {
+ {-1.0*geometry::math::pi<double>() - EPS, geometry::math::pi<double>()/4.0 + EPS},
+ {-1.0*geometry::math::pi<double>() + north_square*geometry::math::pi<double>()/2.0- EPS, geometry::math::pi<double>()/4.0 + EPS},
+ {-1.0*geometry::math::pi<double>() + north_square*geometry::math::pi<double>()/2.0- EPS, 3*geometry::math::pi<double>()/4.0 + EPS},
+ {-1.0*geometry::math::pi<double>() + (north_square + 1.0)*geometry::math::pi<double>()/2.0 + EPS, 3*geometry::math::pi<double>()/4.0 + EPS},
+ {-1.0*geometry::math::pi<double>() + (north_square + 1.0)*geometry::math::pi<double>()/2.0 + EPS, geometry::math::pi<double>()/4.0 + EPS},
+ {geometry::math::pi<double>() + EPS, geometry::math::pi<double>()/4.0 + EPS},
+ {geometry::math::pi<double>() + EPS, -1.0*geometry::math::pi<double>()/4.0 - EPS},
+ {-1.0*geometry::math::pi<double>() + (south_square + 1.0)*geometry::math::pi<double>()/2.0 + EPS, -1.0*geometry::math::pi<double>()/4.0 - EPS},
+ {-1.0*geometry::math::pi<double>() + (south_square + 1.0)*geometry::math::pi<double>()/2.0 + EPS, -3.0*geometry::math::pi<double>()/4.0 - EPS},
+ {-1.0*geometry::math::pi<double>() + south_square*geometry::math::pi<double>()/2.0 - EPS, -3.0*geometry::math::pi<double>()/4.0 - EPS},
+ {-1.0*geometry::math::pi<double>() + south_square*geometry::math::pi<double>()/2.0 - EPS, -1.0*geometry::math::pi<double>()/4.0 - EPS},
+ {-1.0*geometry::math::pi<double>() - EPS, -1.0*geometry::math::pi<double>()/4.0 - EPS}};
+ return pnpoly((int)sizeof(rhealpixVertsJit)/
+ sizeof(rhealpixVertsJit[0]), rhealpixVertsJit, x, y);
+ }
+ }
+ /**
+ * Return the authalic latitude of latitude alpha (if inverse=0) or
+ * return the approximate latitude of authalic latitude alpha (if inverse=1).
+ * P contains the relavent ellipsoid parameters.
+ **/
+ template <typename Parameters>
+ double auth_lat(const Parameters& par, const par_healpix& proj_parm, double alpha, int inverse) {
+ if (inverse == 0) {
+ /* Authalic latitude. */
+ double q = pj_qsfn(sin(alpha), par.e, 1.0 - par.es);
+ double qp = proj_parm.qp;
+ double ratio = q/qp;
+ if (fabsl(ratio) > 1) {
+ /* Rounding error. */
+ ratio = pj_sign(ratio);
+ }
+ return asin(ratio);
+ } else {
+ /* Approximation to inverse authalic latitude. */
+ return pj_authlat(alpha, proj_parm.apa);
+ }
+ }
+ /**
+ * Return the HEALPix projection of the longitude-latitude point lp on
+ * the unit sphere.
+ **/
+ void healpix_sphere(double const& lp_lam, double const& lp_phi, double& xy_x, double& xy_y) {
+ double lam = lp_lam;
+ double phi = lp_phi;
+ double phi0 = asin(2.0/3.0);
+
+ /* equatorial region */
+ if ( fabsl(phi) <= phi0) {
+ xy_x = lam;
+ xy_y = 3.0*geometry::math::pi<double>()/8.0*sin(phi);
+ } else {
+ double lamc;
+ double sigma = sqrt(3.0*(1 - fabsl(sin(phi))));
+ double cn = floor(2*lam / geometry::math::pi<double>() + 2);
+ if (cn >= 4) {
+ cn = 3;
+ }
+ lamc = -3*geometry::math::pi<double>()/4 + (geometry::math::pi<double>()/2)*cn;
+ xy_x = lamc + (lam - lamc)*sigma;
+ xy_y = pj_sign(phi)*geometry::math::pi<double>()/4*(2 - sigma);
+ }
+ return;
+ }
+ /**
+ * Return the inverse of healpix_sphere().
+ **/
+ void healpix_sphere_inverse(double const& xy_x, double const& xy_y, double& lp_lam, double& lp_phi) {
+
+ double x = xy_x;
+ double y = xy_y;
+ double y0 = geometry::math::pi<double>()/4.0;
+ /* Equatorial region. */
+ if (fabsl(y) <= y0) {
+ lp_lam = x;
+ lp_phi = asin(8.0*y/(3.0*geometry::math::pi<double>()));
+ } else if (fabsl(y) < geometry::math::pi<double>()/2.0) {
+ double cn = floor(2.0*x/geometry::math::pi<double>() + 2.0);
+ double xc, tau;
+ if (cn >= 4) {
+ cn = 3;
+ }
+ xc = -3.0*geometry::math::pi<double>()/4.0 + (geometry::math::pi<double>()/2.0)*cn;
+ tau = 2.0 - 4.0*fabsl(y)/geometry::math::pi<double>();
+ lp_lam = xc + (x - xc)/tau;
+ lp_phi = pj_sign(y)*asin(1.0 - pow(tau , 2.0)/3.0);
+ } else {
+ lp_lam = -1.0*geometry::math::pi<double>();
+ lp_phi = pj_sign(y)*geometry::math::pi<double>()/2.0;
+ }
+ return;
+ }
+ /**
+ * Return the vector sum a + b, where a and b are 2-dimensional vectors.
+ * @param ret holds a + b.
+ **/
+ static void vector_add(double a[2], double b[2], double *ret) {
+ int i;
+ for(i = 0; i < 2; i++) {
+ ret[i] = a[i] + b[i];
+ }
+ }
+ /**
+ * Return the vector difference a - b, where a and b are 2-dimensional vectors.
+ * @param ret holds a - b.
+ **/
+ static void vector_sub(double a[2], double b[2], double*ret) {
+ int i;
+ for(i = 0; i < 2; i++) {
+ ret[i] = a[i] - b[i];
+ }
+ }
+ /**
+ * Return the 2 x 1 matrix product a*b, where a is a 2 x 2 matrix and
+ * b is a 2 x 1 matrix.
+ * @param ret holds a*b.
+ **/
+ static void dot_product(double a[2][2], double b[2], double *ret) {
+ int i, j;
+ int length = 2;
+ for(i = 0; i < length; i++) {
+ ret[i] = 0;
+ for(j = 0; j < length; j++) {
+ ret[i] += a[i][j]*b[j];
+ }
+ }
+ }
+ /**
+ * Return the number of the polar cap, the pole point coordinates, and
+ * the region that (x, y) lies in.
+ * If inverse=0, then assume (x,y) lies in the image of the HEALPix
+ * projection of the unit sphere.
+ * If inverse=1, then assume (x,y) lies in the image of the
+ * (north_square, south_square)-rHEALPix projection of the unit sphere.
+ **/
+ static CapMap get_cap(double x, double y, int north_square, int south_square,
+ int inverse) {
+ CapMap capmap;
+ double c;
+ capmap.x = x;
+ capmap.y = y;
+ if (inverse == 0) {
+ if (y > geometry::math::pi<double>()/4.0) {
+ capmap.region = CapMap::north;
+ c = geometry::math::pi<double>()/2.0;
+ } else if (y < -1*geometry::math::pi<double>()/4.0) {
+ capmap.region = CapMap::south;
+ c = -1*geometry::math::pi<double>()/2.0;
+ } else {
+ capmap.region = CapMap::equatorial;
+ capmap.cn = 0;
+ return capmap;
+ }
+ /* polar region */
+ if (x < -1*geometry::math::pi<double>()/2.0) {
+ capmap.cn = 0;
+ capmap.x = (-1*3.0*geometry::math::pi<double>()/4.0);
+ capmap.y = c;
+ } else if (x >= -1*geometry::math::pi<double>()/2.0 && x < 0) {
+ capmap.cn = 1;
+ capmap.x = -1*geometry::math::pi<double>()/4.0;
+ capmap.y = c;
+ } else if (x >= 0 && x < geometry::math::pi<double>()/2.0) {
+ capmap.cn = 2;
+ capmap.x = geometry::math::pi<double>()/4.0;
+ capmap.y = c;
+ } else {
+ capmap.cn = 3;
+ capmap.x = 3.0*geometry::math::pi<double>()/4.0;
+ capmap.y = c;
+ }
+ return capmap;
+ } else {
+ double eps;
+ if (y > geometry::math::pi<double>()/4.0) {
+ capmap.region = CapMap::north;
+ capmap.x = (-3.0*geometry::math::pi<double>()/4.0 + north_square*geometry::math::pi<double>()/2.0);
+ capmap.y = geometry::math::pi<double>()/2.0;
+ x = x - north_square*geometry::math::pi<double>()/2.0;
+ } else if (y < -1*geometry::math::pi<double>()/4.0) {
+ capmap.region = CapMap::south;
+ capmap.x = (-3.0*geometry::math::pi<double>()/4.0 + south_square*geometry::math::pi<double>()/2);
+ capmap.y = -1*geometry::math::pi<double>()/2.0;
+ x = x - south_square*geometry::math::pi<double>()/2.0;
+ } else {
+ capmap.region = CapMap::equatorial;
+ capmap.cn = 0;
+ return capmap;
+ }
+ /* Polar Region, find the HEALPix polar cap number that
+ x, y moves to when rHEALPix polar square is disassembled. */
+ eps = 1e-15; /* Kludge. Fuzz to avoid some rounding errors. */
+ if (capmap.region == CapMap::north) {
+ if (y >= -1*x - geometry::math::pi<double>()/4.0 - eps && y < x + 5.0*geometry::math::pi<double>()/4.0 - eps) {
+ capmap.cn = (north_square + 1) % 4;
+ } else if (y > -1*x -1*geometry::math::pi<double>()/4.0 + eps && y >= x + 5.0*geometry::math::pi<double>()/4.0 - eps) {
+ capmap.cn = (north_square + 2) % 4;
+ } else if (y <= -1*x -1*geometry::math::pi<double>()/4.0 + eps && y > x + 5.0*geometry::math::pi<double>()/4.0 + eps) {
+ capmap.cn = (north_square + 3) % 4;
+ } else {
+ capmap.cn = north_square;
+ }
+ } else if (capmap.region == CapMap::south) {
+ if (y <= x + geometry::math::pi<double>()/4.0 + eps && y > -1*x - 5.0*geometry::math::pi<double>()/4 + eps) {
+ capmap.cn = (south_square + 1) % 4;
+ } else if (y < x + geometry::math::pi<double>()/4.0 - eps && y <= -1*x - 5.0*geometry::math::pi<double>()/4.0 + eps) {
+ capmap.cn = (south_square + 2) % 4;
+ } else if (y >= x + geometry::math::pi<double>()/4.0 - eps && y < -1*x - 5.0*geometry::math::pi<double>()/4.0 - eps) {
+ capmap.cn = (south_square + 3) % 4;
+ } else {
+ capmap.cn = south_square;
+ }
+ }
+ return capmap;
+ }
+ }
+ /**
+ * Rearrange point (x, y) in the HEALPix projection by
+ * combining the polar caps into two polar squares.
+ * Put the north polar square in position north_square and
+ * the south polar square in position south_square.
+ * If inverse=1, then uncombine the polar caps.
+ * @param north_square integer between 0 and 3.
+ * @param south_square integer between 0 and 3.
+ **/
+ static void combine_caps(double& xy_x, double& xy_y, int north_square, int south_square,
+ int inverse) {
+
+ double v[2];
+ double a[2];
+ double vector[2];
+ double v_min_c[2];
+ double ret_dot[2];
+ CapMap capmap = get_cap(xy_x, xy_y, north_square, south_square, inverse);
+ if (capmap.region == CapMap::equatorial) {
+ xy_x = capmap.x;
+ xy_y = capmap.y;
+ return;
+ }
+ v[0] = xy_x;
+ v[1] = xy_y;
+ if (inverse == 0) {
+ /* Rotate (xy_x, xy_y) about its polar cap tip and then translate it to
+ north_square or south_square. */
+ int pole = 0;
+ double (*tmpRot)[2];
+ double c[2] = {capmap.x, capmap.y};
+ if (capmap.region == CapMap::north) {
+ pole = north_square;
+ a[0] = (-3.0*geometry::math::pi<double>()/4.0 + pole*geometry::math::pi<double>()/2);
+ a[1] = (geometry::math::pi<double>()/2.0 + pole*0);
+ tmpRot = rot[get_rotate_index(capmap.cn - pole)];
+ vector_sub(v, c, v_min_c);
+ dot_product(tmpRot, v_min_c, ret_dot);
+ vector_add(ret_dot, a, vector);
+ } else {
+ pole = south_square;
+ a[0] = (-3.0*geometry::math::pi<double>()/4.0 + pole*geometry::math::pi<double>()/2);
+ a[1] = (geometry::math::pi<double>()/-2.0 + pole*0);
+ tmpRot = rot[get_rotate_index(-1*(capmap.cn - pole))];
+ vector_sub(v, c, v_min_c);
+ dot_product(tmpRot, v_min_c, ret_dot);
+ vector_add(ret_dot, a, vector);
+ }
+ xy_x = vector[0];
+ xy_y = vector[1];
+ return;
+ } else {
+ /* Inverse function.
+ Unrotate (xy_x, xy_y) and then translate it back. */
+ int pole = 0;
+ double (*tmpRot)[2];
+ double c[2] = {capmap.x, capmap.y};
+ /* disassemble */
+ if (capmap.region == CapMap::north) {
+ pole = north_square;
+ a[0] = (-3.0*geometry::math::pi<double>()/4.0 + capmap.cn*geometry::math::pi<double>()/2);
+ a[1] = (geometry::math::pi<double>()/2.0 + capmap.cn*0);
+ tmpRot = rot[get_rotate_index(-1*(capmap.cn - pole))];
+ vector_sub(v, c, v_min_c);
+ dot_product(tmpRot, v_min_c, ret_dot);
+ vector_add(ret_dot, a, vector);
+ } else {
+ pole = south_square;
+ a[0] = (-3.0*geometry::math::pi<double>()/4.0 + capmap.cn*geometry::math::pi<double>()/2);
+ a[1] = (geometry::math::pi<double>()/-2.0 + capmap.cn*0);
+ tmpRot = rot[get_rotate_index(capmap.cn - pole)];
+ vector_sub(v, c, v_min_c);
+ dot_product(tmpRot, v_min_c, ret_dot);
+ vector_add(ret_dot, a, vector);
+ }
+ xy_x = vector[0];
+ xy_y = vector[1];
+ return;
+ }
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_healpix_ellipsoid : public base_t_fi<base_healpix_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_healpix m_proj_parm;
+
+ inline base_healpix_ellipsoid(const Parameters& par)
+ : base_t_fi<base_healpix_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ // FORWARD(e_healpix_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 0);
+ return healpix_sphere(lp_lon, lp_lat, xy_x, xy_y);
+ }
+
+ // INVERSE(e_healpix_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ /* Check whether (x, y) lies in the HEALPix image. */
+ if (in_image(xy_x, xy_y, 0, 0, 0) == 0) {
+ lp_lon = HUGE_VAL;
+ lp_lat = HUGE_VAL;
+ throw proj_exception(-15);
+ return;
+ }
+ healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat);
+ lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 1);
+ }
+
+ static inline std::string get_name()
+ {
+ return "healpix_ellipsoid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_healpix_spheroid : public base_t_fi<base_healpix_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_healpix m_proj_parm;
+
+ inline base_healpix_spheroid(const Parameters& par)
+ : base_t_fi<base_healpix_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ // FORWARD(s_healpix_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ return healpix_sphere(lp_lon, lp_lat, xy_x, xy_y);
+ }
+
+ // INVERSE(s_healpix_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ /* Check whether (x, y) lies in the HEALPix image */
+ if (in_image(xy_x, xy_y, 0, 0, 0) == 0) {
+ lp_lon = HUGE_VAL;
+ lp_lat = HUGE_VAL;
+ throw proj_exception(-15);
+ return;
+ }
+ return healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat);
+ }
+
+ static inline std::string get_name()
+ {
+ return "healpix_spheroid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_rhealpix_ellipsoid : public base_t_fi<base_rhealpix_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_healpix m_proj_parm;
+
+ inline base_rhealpix_ellipsoid(const Parameters& par)
+ : base_t_fi<base_rhealpix_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ // FORWARD(e_rhealpix_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 0);
+ healpix_sphere(lp_lon, lp_lat, xy_x, xy_y);
+ combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 0);
+ }
+
+ // INVERSE(e_rhealpix_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ /* Check whether (x, y) lies in the rHEALPix image. */
+ if (in_image(xy_x, xy_y, 1, this->m_proj_parm.north_square, this->m_proj_parm.south_square) == 0) {
+ lp_lon = HUGE_VAL;
+ lp_lat = HUGE_VAL;
+ throw proj_exception(-15);
+ return;
+ }
+ combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 1);
+ healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat);
+ lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 1);
+ }
+
+ static inline std::string get_name()
+ {
+ return "rhealpix_ellipsoid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_rhealpix_spheroid : public base_t_fi<base_rhealpix_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_healpix m_proj_parm;
+
+ inline base_rhealpix_spheroid(const Parameters& par)
+ : base_t_fi<base_rhealpix_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ // FORWARD(s_rhealpix_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ healpix_sphere(lp_lon, lp_lat, xy_x, xy_y);
+ combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 0);
+ }
+
+ // INVERSE(s_rhealpix_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ /* Check whether (x, y) lies in the rHEALPix image. */
+ if (in_image(xy_x, xy_y, 1, this->m_proj_parm.north_square, this->m_proj_parm.south_square) == 0) {
+ lp_lon = HUGE_VAL;
+ lp_lat = HUGE_VAL;
+ throw proj_exception(-15);
+ return;
+ }
+ combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 1);
+ return healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat);
+ }
+
+ static inline std::string get_name()
+ {
+ return "rhealpix_spheroid";
+ }
+
+ };
+
+ // HEALPix
+ template <typename Parameters>
+ void setup_healpix(Parameters& par, par_healpix& proj_parm)
+ {
+ if (par.es) {
+ pj_authset(par.es, proj_parm.apa); /* For auth_lat(). */
+ proj_parm.qp = pj_qsfn(1.0, par.e, par.one_es); /* For auth_lat(). */
+ par.a = par.a*sqrt(0.5*proj_parm.qp); /* Set par.a to authalic radius. */
+ par.ra = 1.0/par.a;
+ } else {
+ }
+ }
+
+ // rHEALPix
+ template <typename Parameters>
+ void setup_rhealpix(Parameters& par, par_healpix& proj_parm)
+ {
+ proj_parm.north_square = pj_param(par.params,"inorth_square").i;
+ proj_parm.south_square = pj_param(par.params,"isouth_square").i;
+ /* Check for valid north_square and south_square inputs. */
+ if (proj_parm.north_square < 0 || proj_parm.north_square > 3) {
+ throw proj_exception(-47);
+ }
+ if (proj_parm.south_square < 0 || proj_parm.south_square > 3) {
+ throw proj_exception(-47);
+ }
+ if (par.es) {
+ pj_authset(par.es, proj_parm.apa); /* For auth_lat(). */
+ proj_parm.qp = pj_qsfn(1.0, par.e, par.one_es); /* For auth_lat(). */
+ par.a = par.a*sqrt(0.5*proj_parm.qp); /* Set par.a to authalic radius. */
+ par.ra = 1.0/par.a;
+ } else {
+ }
+ }
+
+ }} // namespace detail::healpix
+ #endif // doxygen
+
+ /*!
+ \brief HEALPix projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_healpix.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct healpix_ellipsoid : public detail::healpix::base_healpix_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline healpix_ellipsoid(const Parameters& par) : detail::healpix::base_healpix_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::healpix::setup_healpix(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief HEALPix projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_healpix.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct healpix_spheroid : public detail::healpix::base_healpix_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline healpix_spheroid(const Parameters& par) : detail::healpix::base_healpix_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::healpix::setup_healpix(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief rHEALPix projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - north_square (integer)
+ - south_square (integer)
+ \par Example
+ \image html ex_rhealpix.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct rhealpix_ellipsoid : public detail::healpix::base_rhealpix_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline rhealpix_ellipsoid(const Parameters& par) : detail::healpix::base_rhealpix_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::healpix::setup_rhealpix(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief rHEALPix projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - north_square (integer)
+ - south_square (integer)
+ \par Example
+ \image html ex_rhealpix.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct rhealpix_spheroid : public detail::healpix::base_rhealpix_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline rhealpix_spheroid(const Parameters& par) : detail::healpix::base_rhealpix_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::healpix::setup_rhealpix(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class healpix_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<healpix_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<healpix_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class rhealpix_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<rhealpix_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<rhealpix_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void healpix_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("healpix", new healpix_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("rhealpix", new rhealpix_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/igh.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/igh.hpp
new file mode 100644
index 0000000000..d4eb9a09a5
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/igh.hpp
@@ -0,0 +1,315 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IGH_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IGH_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.hpp>
+#include <boost/shared_ptr.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/gn_sinu.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/moll.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace igh
+ {
+
+ template <typename Geographic, typename Cartesian>
+ struct par_igh
+ {
+ boost::shared_ptr<projection<Geographic, Cartesian> > pj[12];
+ double dy0;
+ };
+
+ static const double d4044118 = (40 + 44/60. + 11.8/3600.) * geometry::math::d2r<double>(); // 40d 44' 11.8" [degrees]
+
+ static const double d10 = 10 * geometry::math::d2r<double>();
+ static const double d20 = 20 * geometry::math::d2r<double>();
+ static const double d30 = 30 * geometry::math::d2r<double>();
+ static const double d40 = 40 * geometry::math::d2r<double>();
+ static const double d50 = 50 * geometry::math::d2r<double>();
+ static const double d60 = 60 * geometry::math::d2r<double>();
+ static const double d80 = 80 * geometry::math::d2r<double>();
+ static const double d90 = 90 * geometry::math::d2r<double>();
+ static const double d100 = 100 * geometry::math::d2r<double>();
+ static const double d140 = 140 * geometry::math::d2r<double>();
+ static const double d160 = 160 * geometry::math::d2r<double>();
+ static const double d180 = 180 * geometry::math::d2r<double>();
+
+ static const double EPSLN = 1.e-10; // allow a little 'slack' on zone edge positions
+
+ // Converted from #define SETUP(n, proj, x_0, y_0, lon_0)
+ template <template <typename, typename, typename> class Entry, typename Parameters, typename Geographic, typename Cartesian>
+ inline void do_setup(int n, Parameters const& par, par_igh<Geographic, Cartesian>& proj_parm, double x_0, double y_0, double lon_0)
+ {
+ Entry<Geographic, Cartesian, Parameters> entry;
+ proj_parm.pj[n-1].reset(entry.create_new(par));
+ proj_parm.pj[n-1]->mutable_params().x0 = x_0;
+ proj_parm.pj[n-1]->mutable_params().y0 = y_0;
+ proj_parm.pj[n-1]->mutable_params().lam0 = lon_0;
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_igh_spheroid : public base_t_fi<base_igh_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_igh<Geographic, Cartesian> m_proj_parm;
+
+ inline base_igh_spheroid(const Parameters& par)
+ : base_t_fi<base_igh_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ int z;
+ if (lp_lat >= d4044118) { // 1|2
+ z = (lp_lon <= -d40 ? 1: 2);
+ }
+ else if (lp_lat >= 0) { // 3|4
+ z = (lp_lon <= -d40 ? 3: 4);
+ }
+ else if (lp_lat >= -d4044118) { // 5|6|7|8
+ if (lp_lon <= -d100) z = 5; // 5
+ else if (lp_lon <= -d20) z = 6; // 6
+ else if (lp_lon <= d80) z = 7; // 7
+ else z = 8; // 8
+ }
+ else { // 9|10|11|12
+ if (lp_lon <= -d100) z = 9; // 9
+ else if (lp_lon <= -d20) z = 10; // 10
+ else if (lp_lon <= d80) z = 11; // 11
+ else z = 12; // 12
+ }
+
+ lp_lon -= this->m_proj_parm.pj[z-1]->params().lam0;
+ this->m_proj_parm.pj[z-1]->fwd(lp_lon, lp_lat, xy_x, xy_y);
+ xy_x += this->m_proj_parm.pj[z-1]->params().x0;
+ xy_y += this->m_proj_parm.pj[z-1]->params().y0;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ const double y90 = this->m_proj_parm.dy0 + sqrt(2.0); // lt=90 corresponds to y=y0+sqrt(2.0)
+
+ int z = 0;
+ if (xy_y > y90+EPSLN || xy_y < -y90+EPSLN) // 0
+ z = 0;
+ else if (xy_y >= d4044118) // 1|2
+ z = (xy_x <= -d40? 1: 2);
+ else if (xy_y >= 0) // 3|4
+ z = (xy_x <= -d40? 3: 4);
+ else if (xy_y >= -d4044118) { // 5|6|7|8
+ if (xy_x <= -d100) z = 5; // 5
+ else if (xy_x <= -d20) z = 6; // 6
+ else if (xy_x <= d80) z = 7; // 7
+ else z = 8; // 8
+ }
+ else { // 9|10|11|12
+ if (xy_x <= -d100) z = 9; // 9
+ else if (xy_x <= -d20) z = 10; // 10
+ else if (xy_x <= d80) z = 11; // 11
+ else z = 12; // 12
+ }
+
+ if (z)
+ {
+ int ok = 0;
+
+ xy_x -= this->m_proj_parm.pj[z-1]->params().x0;
+ xy_y -= this->m_proj_parm.pj[z-1]->params().y0;
+ this->m_proj_parm.pj[z-1]->inv(xy_x, xy_y, lp_lon, lp_lat);
+ lp_lon += this->m_proj_parm.pj[z-1]->params().lam0;
+
+ switch (z) {
+ case 1: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d40+EPSLN) ||
+ ((lp_lon >= -d40-EPSLN && lp_lon <= -d10+EPSLN) &&
+ (lp_lat >= d60-EPSLN && lp_lat <= d90+EPSLN)); break;
+ case 2: ok = (lp_lon >= -d40-EPSLN && lp_lon <= d180+EPSLN) ||
+ ((lp_lon >= -d180-EPSLN && lp_lon <= -d160+EPSLN) &&
+ (lp_lat >= d50-EPSLN && lp_lat <= d90+EPSLN)) ||
+ ((lp_lon >= -d50-EPSLN && lp_lon <= -d40+EPSLN) &&
+ (lp_lat >= d60-EPSLN && lp_lat <= d90+EPSLN)); break;
+ case 3: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d40+EPSLN); break;
+ case 4: ok = (lp_lon >= -d40-EPSLN && lp_lon <= d180+EPSLN); break;
+ case 5: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d100+EPSLN); break;
+ case 6: ok = (lp_lon >= -d100-EPSLN && lp_lon <= -d20+EPSLN); break;
+ case 7: ok = (lp_lon >= -d20-EPSLN && lp_lon <= d80+EPSLN); break;
+ case 8: ok = (lp_lon >= d80-EPSLN && lp_lon <= d180+EPSLN); break;
+ case 9: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d100+EPSLN); break;
+ case 10: ok = (lp_lon >= -d100-EPSLN && lp_lon <= -d20+EPSLN); break;
+ case 11: ok = (lp_lon >= -d20-EPSLN && lp_lon <= d80+EPSLN); break;
+ case 12: ok = (lp_lon >= d80-EPSLN && lp_lon <= d180+EPSLN); break;
+ }
+
+ z = (!ok? 0: z); // projectable?
+ }
+ // if (!z) pj_errno = -15; // invalid x or y
+ if (!z) lp_lon = HUGE_VAL;
+ if (!z) lp_lat = HUGE_VAL;
+ }
+
+ static inline std::string get_name()
+ {
+ return "igh_spheroid";
+ }
+
+ };
+
+ // Interrupted Goode Homolosine
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ void setup_igh(Parameters& par, par_igh<Geographic, Cartesian>& proj_parm)
+ {
+ /*
+ Zones:
+
+ -180 -40 180
+ +--------------+-------------------------+ Zones 1,2,9,10,11 & 12:
+ |1 |2 | Mollweide projection
+ | | |
+ +--------------+-------------------------+ Zones 3,4,5,6,7 & 8:
+ |3 |4 | Sinusoidal projection
+ | | |
+ 0 +-------+------+-+-----------+-----------+
+ |5 |6 |7 |8 |
+ | | | | |
+ +-------+--------+-----------+-----------+
+ |9 |10 |11 |12 |
+ | | | | |
+ +-------+--------+-----------+-----------+
+ -180 -100 -20 80 180
+ */
+
+
+ double lp_lam = 0, lp_phi = d4044118;
+ double xy1_x, xy1_y;
+ double xy3_x, xy3_y;
+
+ // sinusoidal zones
+ do_setup<sinu_entry>(3, par, proj_parm, -d100, 0, -d100);
+ do_setup<sinu_entry>(4, par, proj_parm, d30, 0, d30);
+ do_setup<sinu_entry>(5, par, proj_parm, -d160, 0, -d160);
+ do_setup<sinu_entry>(6, par, proj_parm, -d60, 0, -d60);
+ do_setup<sinu_entry>(7, par, proj_parm, d20, 0, d20);
+ do_setup<sinu_entry>(8, par, proj_parm, d140, 0, d140);
+
+ // mollweide zones
+ do_setup<moll_entry>(1, par, proj_parm, -d100, 0, -d100);
+
+ // y0 ?
+ proj_parm.pj[0]->fwd(lp_lam, lp_phi, xy1_x, xy1_y); // zone 1
+ proj_parm.pj[2]->fwd(lp_lam, lp_phi, xy3_x, xy3_y); // zone 3
+ // y0 + xy1_y = xy3_y for lt = 40d44'11.8"
+ proj_parm.dy0 = xy3_y - xy1_y;
+
+ proj_parm.pj[0]->mutable_params().y0 = proj_parm.dy0;
+
+ // mollweide zones (cont'd)
+ do_setup<moll_entry>( 2, par, proj_parm, d30, proj_parm.dy0, d30);
+ do_setup<moll_entry>( 9, par, proj_parm, -d160, -proj_parm.dy0, -d160);
+ do_setup<moll_entry>(10, par, proj_parm, -d60, -proj_parm.dy0, -d60);
+ do_setup<moll_entry>(11, par, proj_parm, d20, -proj_parm.dy0, d20);
+ do_setup<moll_entry>(12, par, proj_parm, d140, -proj_parm.dy0, d140);
+
+ par.es = 0.;
+ }
+
+ }} // namespace detail::igh
+ #endif // doxygen
+
+ /*!
+ \brief Interrupted 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_igh.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct igh_spheroid : public detail::igh::base_igh_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline igh_spheroid(const Parameters& par) : detail::igh::base_igh_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::igh::setup_igh(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class igh_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<igh_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void igh_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("igh", new igh_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IGH_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/imw_p.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/imw_p.hpp
new file mode 100644
index 0000000000..0f6476303b
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/imw_p.hpp
@@ -0,0 +1,296 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace imw_p
+ {
+
+ static const double TOL = 1e-10;
+ static const double EPS = 1e-10;
+
+ struct XY { double x, y; }; // specific for IMW_P
+
+ 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>
+ static 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>
+ static XY
+ loc_for(double const& lp_lam, double const& lp_phi, Parameters const& par, par_imw_p const& proj_parm, double *yc) {
+ XY 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>
+ static void
+ xy(Parameters const& par, par_imw_p const& 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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double yc = 0;
+ XY xy = loc_for(lp_lon, lp_lat, this->m_par, m_proj_parm, &yc);
+ xy_x = xy.x; xy_y = xy.y;
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ XY 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "imw_p_ellipsoid";
+ }
+
+ };
+
+ // 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;
+
+ if (!pj_enfn(par.es, proj_parm.en)) throw proj_exception(0);
+ 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 * geometry::math::r2d<double>());
+ if (sig <= 60) sig = 2.;
+ else if (sig <= 76) sig = 4.;
+ else sig = 8.;
+ proj_parm.lam_1 = sig * geometry::math::d2r<double>();
+ }
+ 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;
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel
+ - lat_2: Latitude of second standard parallel
+ - lon_1 (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/isea.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/isea.hpp
new file mode 100644
index 0000000000..b4fc25a2c6
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/isea.hpp
@@ -0,0 +1,1249 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// This code was entirely written by Nathan Wagner
+// and is in the public domain.
+
+// 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/core/ignore_unused.hpp>
+#include <boost/geometry/util/math.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 projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace isea
+ {
+
+ static const double E = 52.62263186;
+ static const double F = 10.81231696;
+ static const double DEG60 = 1.04719755119659774614;
+ static const double DEG120 = 2.09439510239319549229;
+ static const double DEG72 = 1.25663706143591729537;
+ static const double DEG90 = 1.57079632679489661922;
+ static const double DEG144 = 2.51327412287183459075;
+ static const double DEG36 = 0.62831853071795864768;
+ static const double DEG108 = 1.88495559215387594306;
+ static const double DEG180 = geometry::math::pi<double>();
+ static const double ISEA_SCALE = 0.8301572857837594396028083;
+ static const double V_LAT = 0.46364760899944494524;
+ static const double E_RAD = 0.91843818702186776133;
+ static const double F_RAD = 0.18871053072122403508;
+ static const double TABLE_G = 0.6615845383;
+ static const double TABLE_H = 0.1909830056;
+ static const double RPRIME = 0.91038328153090290025;
+ static const double PRECISION = 0.0000000000005;
+ static const double ISEA_STD_LAT = 1.01722196792335072101;
+ static const double ISEA_STD_LON = .19634954084936207740;
+
+ #define DOWNTRI(tri) (((tri - 1) / 5) % 2 == 1)
+
+ /*
+ * Proj 4 provides its own entry points into
+ * the code, so none of the library functions
+ * need to be global
+ */
+
+ struct hex {
+ int iso;
+ int x, y, z;
+ };
+
+ /* y *must* be positive down as the xy /iso conversion assumes this */
+ static
+ int hex_xy(struct hex *h) {
+ if (!h->iso) return 1;
+ if (h->x >= 0) {
+ h->y = -h->y - (h->x+1)/2;
+ } else {
+ /* need to round toward -inf, not toward zero, so x-1 */
+ h->y = -h->y - h->x/2;
+ }
+ h->iso = 0;
+
+ return 1;
+ }
+
+ static
+ int hex_iso(struct hex *h) {
+ if (h->iso) return 1;
+
+ if (h->x >= 0) {
+ h->y = (-h->y - (h->x+1)/2);
+ } else {
+ /* need to round toward -inf, not toward zero, so x-1 */
+ h->y = (-h->y - (h->x)/2);
+ }
+
+ h->z = -h->x - h->y;
+ h->iso = 1;
+ return 1;
+ }
+
+ static
+ int hexbin2(int horizontal, double width, double x, double y,
+ int *i, int *j) {
+ double z, rx, ry, rz;
+ double abs_dx, abs_dy, abs_dz;
+ int ix, iy, iz, s;
+ struct hex h;
+
+ x = x / cos(30 * geometry::math::d2r<double>()); /* rotated X coord */
+ y = y - x / 2.0; /* adjustment for rotated X */
+
+ /* adjust for actual hexwidth */
+ x /= width;
+ y /= width;
+
+ z = -x - y;
+
+ ix = rx = floor(x + 0.5);
+ iy = ry = floor(y + 0.5);
+ iz = rz = floor(z + 0.5);
+
+ s = ix + iy + iz;
+
+ if (s) {
+ abs_dx = fabs(rx - x);
+ abs_dy = fabs(ry - y);
+ abs_dz = fabs(rz - z);
+
+ if (abs_dx >= abs_dy && abs_dx >= abs_dz) {
+ ix -= s;
+ } else if (abs_dy >= abs_dx && abs_dy >= abs_dz) {
+ iy -= s;
+ } else {
+ iz -= s;
+ }
+ }
+ h.x = ix;
+ h.y = iy;
+ h.z = iz;
+ h.iso = 1;
+
+ hex_xy(&h);
+ *i = h.x;
+ *j = h.y;
+ return ix * 100 + iy;
+ }
+
+ enum isea_poly { ISEA_NONE, ISEA_ICOSAHEDRON = 20 };
+ enum isea_topology { ISEA_HEXAGON=6, ISEA_TRIANGLE=3, ISEA_DIAMOND=4 };
+ enum isea_address_form { ISEA_GEO, ISEA_Q2DI, ISEA_SEQNUM, ISEA_INTERLEAVE,
+ ISEA_PLANE, ISEA_Q2DD, ISEA_PROJTRI, ISEA_VERTEX2DD, ISEA_HEX
+ };
+
+ struct isea_dgg {
+ int polyhedron; /* ignored, icosahedron */
+ double o_lat, o_lon, o_az; /* orientation, radians */
+ int pole; /* true if standard snyder */
+ int topology; /* ignored, hexagon */
+ int aperture; /* valid values depend on partitioning method */
+ int resolution;
+ double radius; /* radius of the earth in meters, ignored 1.0 */
+ int output; /* an isea_address_form */
+ int triangle; /* triangle of last transformed point */
+ int quad; /* quad of last transformed point */
+ unsigned long serial;
+ };
+
+ struct isea_pt {
+ double x, y;
+ };
+
+ struct isea_geo {
+ double lon, lat;
+ };
+
+ struct isea_address {
+ int type; /* enum isea_address_form */
+ int number;
+ double x,y; /* or i,j or lon,lat depending on type */
+ };
+
+ /* ENDINC */
+
+ enum snyder_polyhedron {
+ SNYDER_POLY_HEXAGON, SNYDER_POLY_PENTAGON,
+ SNYDER_POLY_TETRAHEDRON, SNYDER_POLY_CUBE,
+ SNYDER_POLY_OCTAHEDRON, SNYDER_POLY_DODECAHEDRON,
+ SNYDER_POLY_ICOSAHEDRON
+ };
+
+ struct snyder_constants {
+ double g, G, theta, ea_w, ea_a, ea_b, g_w, g_a, g_b;
+ };
+
+ /* TODO put these in radians to avoid a later conversion */
+ static
+ struct snyder_constants constants[] = {
+ {23.80018260, 62.15458023, 60.0, 3.75, 1.033, 0.968, 5.09, 1.195, 1.0},
+ {20.07675127, 55.69063953, 54.0, 2.65, 1.030, 0.983, 3.59, 1.141, 1.027},
+ {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {37.37736814, 36.0, 30.0, 17.27, 1.163, 0.860, 13.14, 1.584, 1.0},
+ };
+
+
+ /* sqrt(5)/M_PI */
+
+ /* 26.565051177 degrees */
+
+
+ static
+ struct isea_geo vertex[] = {
+ {0.0, DEG90},
+ {DEG180, V_LAT},
+ {-DEG108, V_LAT},
+ {-DEG36, V_LAT},
+ {DEG36, V_LAT},
+ {DEG108, V_LAT},
+ {-DEG144, -V_LAT},
+ {-DEG72, -V_LAT},
+ {0.0, -V_LAT},
+ {DEG72, -V_LAT},
+ {DEG144, -V_LAT},
+ {0.0, -DEG90}
+ };
+
+ /* TODO make an isea_pt array of the vertices as well */
+
+ static int tri_v1[] = {0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 2, 3, 4, 5, 1, 11, 11, 11, 11, 11};
+
+ /* 52.62263186 */
+
+ /* 10.81231696 */
+
+ /* triangle Centers */
+ struct isea_geo icostriangles[] = {
+ {0.0, 0.0},
+ {-DEG144, E_RAD},
+ {-DEG72, E_RAD},
+ {0.0, E_RAD},
+ {DEG72, E_RAD},
+ {DEG144, E_RAD},
+ {-DEG144, F_RAD},
+ {-DEG72, F_RAD},
+ {0.0, F_RAD},
+ {DEG72, F_RAD},
+ {DEG144, F_RAD},
+ {-DEG108, -F_RAD},
+ {-DEG36, -F_RAD},
+ {DEG36, -F_RAD},
+ {DEG108, -F_RAD},
+ {DEG180, -F_RAD},
+ {-DEG108, -E_RAD},
+ {-DEG36, -E_RAD},
+ {DEG36, -E_RAD},
+ {DEG108, -E_RAD},
+ {DEG180, -E_RAD},
+ };
+
+ static double
+ az_adjustment(int triangle)
+ {
+ double adj;
+
+ struct isea_geo v;
+ struct isea_geo c;
+
+ v = vertex[tri_v1[triangle]];
+ c = icostriangles[triangle];
+
+ /* TODO looks like the adjustment is always either 0 or 180 */
+ /* at least if you pick your vertex carefully */
+ adj = atan2(cos(v.lat) * sin(v.lon - c.lon),
+ cos(c.lat) * sin(v.lat)
+ - sin(c.lat) * cos(v.lat) * cos(v.lon - c.lon));
+ return adj;
+ }
+
+ /* R tan(g) sin(60) */
+
+ /* H = 0.25 R tan g = */
+
+
+ static
+ struct isea_pt
+ isea_triangle_xy(int triangle)
+ {
+ struct isea_pt c;
+ double Rprime = 0.91038328153090290025;
+
+ triangle = (triangle - 1) % 20;
+
+ c.x = TABLE_G * ((triangle % 5) - 2) * 2.0;
+ if (triangle > 9) {
+ c.x += TABLE_G;
+ }
+ switch (triangle / 5) {
+ case 0:
+ c.y = 5.0 * TABLE_H;
+ break;
+ case 1:
+ c.y = TABLE_H;
+ break;
+ case 2:
+ c.y = -TABLE_H;
+ break;
+ case 3:
+ c.y = -5.0 * TABLE_H;
+ break;
+ default:
+ /* should be impossible */
+ throw proj_exception();
+ };
+ c.x *= Rprime;
+ c.y *= Rprime;
+
+ return c;
+ }
+
+ /* snyder eq 14 */
+ static double
+ sph_azimuth(double f_lon, double f_lat, double t_lon, double t_lat)
+ {
+ double az;
+
+ az = atan2(cos(t_lat) * sin(t_lon - f_lon),
+ cos(f_lat) * sin(t_lat)
+ - sin(f_lat) * cos(t_lat) * cos(t_lon - f_lon)
+ );
+ return az;
+ }
+
+ /* coord needs to be in radians */
+ static
+ int
+ isea_snyder_forward(struct isea_geo * ll, struct isea_pt * out)
+ {
+ int i;
+
+ /*
+ * spherical distance from center of polygon face to any of its
+ * vertexes on the globe
+ */
+ double g;
+
+ /*
+ * spherical angle between radius vector to center and adjacent edge
+ * of spherical polygon on the globe
+ */
+ double G;
+
+ /*
+ * plane angle between radius vector to center and adjacent edge of
+ * plane polygon
+ */
+ double theta;
+
+ /* additional variables from snyder */
+ double q, Rprime, H, Ag, Azprime, Az, dprime, f, rho,
+ x, y;
+
+ /* variables used to store intermediate results */
+ double cot_theta, tan_g, az_offset;
+
+ /* how many multiples of 60 degrees we adjust the azimuth */
+ int Az_adjust_multiples;
+
+ struct snyder_constants c;
+
+ /*
+ * TODO by locality of reference, start by trying the same triangle
+ * as last time
+ */
+
+ /* TODO put these constants in as radians to begin with */
+ c = constants[SNYDER_POLY_ICOSAHEDRON];
+ theta = c.theta * geometry::math::d2r<double>();
+ g = c.g * geometry::math::d2r<double>();
+ G = c.G * geometry::math::d2r<double>();
+
+ for (i = 1; i <= 20; i++) {
+ double z;
+ struct isea_geo center;
+
+ center = icostriangles[i];
+
+ /* step 1 */
+ #if 0
+ z = sph_distance(center.lon, center.lat, ll->lon, ll->lat);
+ #else
+ z = acos(sin(center.lat) * sin(ll->lat)
+ + cos(center.lat) * cos(ll->lat) * cos(ll->lon - center.lon));
+ #endif
+
+ /* not on this triangle */
+ if (z > g + 0.000005) { /* TODO DBL_EPSILON */
+ continue;
+ }
+ Az = sph_azimuth(ll->lon, ll->lat, center.lon, center.lat);
+
+ Az = atan2(cos(ll->lat) * sin(ll->lon - center.lon),
+ cos(center.lat) * sin(ll->lat)
+ - sin(center.lat) * cos(ll->lat) * cos(ll->lon - center.lon)
+ );
+
+ /* step 2 */
+
+ /* This calculates "some" vertex coordinate */
+ az_offset = az_adjustment(i);
+
+ Az -= az_offset;
+
+ /* TODO I don't know why we do this. It's not in snyder */
+ /* maybe because we should have picked a better vertex */
+ if (Az < 0.0) {
+ Az += geometry::math::two_pi<double>();
+ }
+ /*
+ * adjust Az for the point to fall within the range of 0 to
+ * 2(90 - theta) or 60 degrees for the hexagon, by
+ * and therefore 120 degrees for the triangle
+ * of the icosahedron
+ * subtracting or adding multiples of 60 degrees to Az and
+ * recording the amount of adjustment
+ */
+
+ Az_adjust_multiples = 0;
+ while (Az < 0.0) {
+ Az += DEG120;
+ Az_adjust_multiples--;
+ }
+ while (Az > DEG120 + DBL_EPSILON) {
+ Az -= DEG120;
+ Az_adjust_multiples++;
+ }
+
+ /* step 3 */
+ cot_theta = 1.0 / tan(theta);
+ tan_g = tan(g); /* TODO this is a constant */
+
+ /* Calculate q from eq 9. */
+ /* TODO cot_theta is cot(30) */
+ q = atan2(tan_g, cos(Az) + sin(Az) * cot_theta);
+
+ /* not in this triangle */
+ if (z > q + 0.000005) {
+ continue;
+ }
+ /* step 4 */
+
+ /* Apply equations 5-8 and 10-12 in order */
+
+ /* eq 5 */
+ /* Rprime = 0.9449322893 * R; */
+ /* R' in the paper is for the truncated */
+ Rprime = 0.91038328153090290025;
+
+ /* eq 6 */
+ H = acos(sin(Az) * sin(G) * cos(g) - cos(Az) * cos(G));
+
+ /* eq 7 */
+ /* Ag = (Az + G + H - DEG180) * M_PI * R * R / DEG180; */
+ Ag = Az + G + H - DEG180;
+
+ /* eq 8 */
+ Azprime = atan2(2.0 * Ag, Rprime * Rprime * tan_g * tan_g - 2.0 * Ag * cot_theta);
+
+ /* eq 10 */
+ /* cot(theta) = 1.73205080756887729355 */
+ dprime = Rprime * tan_g / (cos(Azprime) + sin(Azprime) * cot_theta);
+
+ /* eq 11 */
+ f = dprime / (2.0 * Rprime * sin(q / 2.0));
+
+ /* eq 12 */
+ rho = 2.0 * Rprime * f * sin(z / 2.0);
+
+ /*
+ * add back the same 60 degree multiple adjustment from step
+ * 2 to Azprime
+ */
+
+ Azprime += DEG120 * Az_adjust_multiples;
+
+ /* calculate rectangular coordinates */
+
+ x = rho * sin(Azprime);
+ y = rho * cos(Azprime);
+
+ /*
+ * TODO
+ * translate coordinates to the origin for the particular
+ * hexagon on the flattened polyhedral map plot
+ */
+
+ out->x = x;
+ out->y = y;
+
+ return i;
+ }
+
+ /*
+ * should be impossible, this implies that the coordinate is not on
+ * any triangle
+ */
+
+ fprintf(stderr, "impossible transform: %f %f is not on any triangle\n",
+ ll->lon * geometry::math::r2d<double>(), ll->lat * geometry::math::r2d<double>());
+
+ throw proj_exception();
+
+ /* not reached */
+ return 0; /* supresses a warning */
+ }
+
+ /*
+ * return the new coordinates of any point in orginal coordinate system.
+ * Define a point (newNPold) in orginal coordinate system as the North Pole in
+ * new coordinate system, and the great circle connect the original and new
+ * North Pole as the lon0 longitude in new coordinate system, given any point
+ * in orginal coordinate system, this function return the new coordinates.
+ */
+
+
+ /* formula from Snyder, Map Projections: A working manual, p31 */
+ /*
+ * old north pole at np in new coordinates
+ * could be simplified a bit with fewer intermediates
+ *
+ * TODO take a result pointer
+ */
+ static
+ struct isea_geo
+ snyder_ctran(struct isea_geo * np, struct isea_geo * pt)
+ {
+ struct isea_geo npt;
+ double alpha, phi, lambda, lambda0, beta, lambdap, phip;
+ double sin_phip;
+ double lp_b; /* lambda prime minus beta */
+ double cos_p, sin_a;
+
+ phi = pt->lat;
+ lambda = pt->lon;
+ alpha = np->lat;
+ beta = np->lon;
+ lambda0 = beta;
+
+ cos_p = cos(phi);
+ sin_a = sin(alpha);
+
+ /* mpawm 5-7 */
+ sin_phip = sin_a * sin(phi) - cos(alpha) * cos_p * cos(lambda - lambda0);
+
+ /* mpawm 5-8b */
+
+ /* use the two argument form so we end up in the right quadrant */
+ lp_b = atan2(cos_p * sin(lambda - lambda0),
+ (sin_a * cos_p * cos(lambda - lambda0) + cos(alpha) * sin(phi)));
+
+ lambdap = lp_b + beta;
+
+ /* normalize longitude */
+ /* TODO can we just do a modulus ? */
+ lambdap = fmod(lambdap, geometry::math::two_pi<double>());
+ while (lambdap > geometry::math::pi<double>())
+ lambdap -= geometry::math::two_pi<double>();
+ while (lambdap < -geometry::math::pi<double>())
+ lambdap += geometry::math::two_pi<double>();
+
+ phip = asin(sin_phip);
+
+ npt.lat = phip;
+ npt.lon = lambdap;
+
+ return npt;
+ }
+
+ static
+ struct isea_geo
+ isea_ctran(struct isea_geo * np, struct isea_geo * pt, double lon0)
+ {
+ struct isea_geo npt;
+
+ np->lon += geometry::math::pi<double>();
+ npt = snyder_ctran(np, pt);
+ np->lon -= geometry::math::pi<double>();
+
+ npt.lon -= (geometry::math::pi<double>() - lon0 + np->lon);
+
+ /*
+ * snyder is down tri 3, isea is along side of tri1 from vertex 0 to
+ * vertex 1 these are 180 degrees apart
+ */
+ npt.lon += geometry::math::pi<double>();
+ /* normalize longitude */
+ npt.lon = fmod(npt.lon, geometry::math::two_pi<double>());
+ while (npt.lon > geometry::math::pi<double>())
+ npt.lon -= geometry::math::two_pi<double>();
+ while (npt.lon < -geometry::math::pi<double>())
+ npt.lon += geometry::math::two_pi<double>();
+
+ return npt;
+ }
+
+ /* in radians */
+
+ /* fuller's at 5.2454 west, 2.3009 N, adjacent at 7.46658 deg */
+
+ static
+ int
+ isea_grid_init(struct isea_dgg * g)
+ {
+ if (!g)
+ return 0;
+
+ g->polyhedron = 20;
+ g->o_lat = ISEA_STD_LAT;
+ g->o_lon = ISEA_STD_LON;
+ g->o_az = 0.0;
+ g->aperture = 4;
+ g->resolution = 6;
+ g->radius = 1.0;
+ g->topology = 6;
+
+ return 1;
+ }
+
+ static
+ int
+ isea_orient_isea(struct isea_dgg * g)
+ {
+ if (!g)
+ return 0;
+ g->o_lat = ISEA_STD_LAT;
+ g->o_lon = ISEA_STD_LON;
+ g->o_az = 0.0;
+ return 1;
+ }
+
+ static
+ int
+ isea_orient_pole(struct isea_dgg * g)
+ {
+ if (!g)
+ return 0;
+ g->o_lat = geometry::math::half_pi<double>();
+ g->o_lon = 0.0;
+ g->o_az = 0;
+ return 1;
+ }
+
+ static
+ int
+ isea_transform(struct isea_dgg * g, struct isea_geo * in,
+ struct isea_pt * out)
+ {
+ struct isea_geo i, pole;
+ int tri;
+
+ pole.lat = g->o_lat;
+ pole.lon = g->o_lon;
+
+ i = isea_ctran(&pole, in, g->o_az);
+
+ tri = isea_snyder_forward(&i, out);
+ out->x *= g->radius;
+ out->y *= g->radius;
+ g->triangle = tri;
+
+ return tri;
+ }
+
+
+ static
+ void
+ isea_rotate(struct isea_pt * pt, double degrees)
+ {
+ double rad;
+
+ double x, y;
+
+ rad = -degrees * geometry::math::d2r<double>();
+ while (rad >= geometry::math::two_pi<double>()) rad -= geometry::math::two_pi<double>();
+ while (rad <= -geometry::math::two_pi<double>()) rad += geometry::math::two_pi<double>();
+
+ x = pt->x * cos(rad) + pt->y * sin(rad);
+ y = -pt->x * sin(rad) + pt->y * cos(rad);
+
+ pt->x = x;
+ pt->y = y;
+ }
+
+ static
+ int isea_tri_plane(int tri, struct isea_pt *pt, double radius) {
+ struct isea_pt tc; /* center of triangle */
+
+ if (DOWNTRI(tri)) {
+ isea_rotate(pt, 180.0);
+ }
+ tc = isea_triangle_xy(tri);
+ tc.x *= radius;
+ tc.y *= radius;
+ pt->x += tc.x;
+ pt->y += tc.y;
+
+ return tri;
+ }
+
+ /* convert projected triangle coords to quad xy coords, return quad number */
+ static
+ int
+ isea_ptdd(int tri, struct isea_pt *pt) {
+ int downtri, quad;
+
+ downtri = (((tri - 1) / 5) % 2 == 1);
+ boost::ignore_unused(downtri);
+ quad = ((tri - 1) % 5) + ((tri - 1) / 10) * 5 + 1;
+
+ isea_rotate(pt, downtri ? 240.0 : 60.0);
+ if (downtri) {
+ pt->x += 0.5;
+ /* pt->y += cos(30.0 * M_PI / 180.0); */
+ pt->y += .86602540378443864672;
+ }
+ return quad;
+ }
+
+ static
+ int
+ isea_dddi_ap3odd(struct isea_dgg *g, int quad, struct isea_pt *pt, struct isea_pt *di)
+ {
+ struct isea_pt v;
+ double hexwidth;
+ double sidelength; /* in hexes */
+ int d, i;
+ int maxcoord;
+ struct hex h;
+
+ /* This is the number of hexes from apex to base of a triangle */
+ sidelength = (pow(2.0, g->resolution) + 1.0) / 2.0;
+
+ /* apex to base is cos(30deg) */
+ hexwidth = cos(geometry::math::pi<double>() / 6.0) / sidelength;
+
+ /* TODO I think sidelength is always x.5, so
+ * (int)sidelength * 2 + 1 might be just as good
+ */
+ maxcoord = (int) (sidelength * 2.0 + 0.5);
+
+ v = *pt;
+ hexbin2(0, hexwidth, v.x, v.y, &h.x, &h.y);
+ h.iso = 0;
+ hex_iso(&h);
+
+ d = h.x - h.z;
+ i = h.x + h.y + h.y;
+
+ /*
+ * you want to test for max coords for the next quad in the same
+ * "row" first to get the case where both are max
+ */
+ if (quad <= 5) {
+ if (d == 0 && i == maxcoord) {
+ /* north pole */
+ quad = 0;
+ d = 0;
+ i = 0;
+ } else if (i == maxcoord) {
+ /* upper right in next quad */
+ quad += 1;
+ if (quad == 6)
+ quad = 1;
+ i = maxcoord - d;
+ d = 0;
+ } else if (d == maxcoord) {
+ /* lower right in quad to lower right */
+ quad += 5;
+ d = 0;
+ }
+ } else if (quad >= 6) {
+ if (i == 0 && d == maxcoord) {
+ /* south pole */
+ quad = 11;
+ d = 0;
+ i = 0;
+ } else if (d == maxcoord) {
+ /* lower right in next quad */
+ quad += 1;
+ if (quad == 11)
+ quad = 6;
+ d = maxcoord - i;
+ i = 0;
+ } else if (i == maxcoord) {
+ /* upper right in quad to upper right */
+ quad = (quad - 4) % 5;
+ i = 0;
+ }
+ }
+
+ di->x = d;
+ di->y = i;
+
+ g->quad = quad;
+ return quad;
+ }
+
+ static
+ int
+ isea_dddi(struct isea_dgg *g, int quad, struct isea_pt *pt, struct isea_pt *di) {
+ struct isea_pt v;
+ double hexwidth;
+ int sidelength; /* in hexes */
+ struct hex h;
+
+ if (g->aperture == 3 && g->resolution % 2 != 0) {
+ return isea_dddi_ap3odd(g, quad, pt, di);
+ }
+ /* todo might want to do this as an iterated loop */
+ if (g->aperture >0) {
+ sidelength = (int) (pow(static_cast<double>(g->aperture), g->resolution / 2.0) + 0.5);
+ } else {
+ sidelength = g->resolution;
+ }
+
+ hexwidth = 1.0 / sidelength;
+
+ v = *pt;
+ isea_rotate(&v, -30.0);
+ hexbin2(0, hexwidth, v.x, v.y, &h.x, &h.y);
+ h.iso = 0;
+ hex_iso(&h);
+
+ /* we may actually be on another quad */
+ if (quad <= 5) {
+ if (h.x == 0 && h.z == -sidelength) {
+ /* north pole */
+ quad = 0;
+ h.z = 0;
+ h.y = 0;
+ h.x = 0;
+ } else if (h.z == -sidelength) {
+ quad = quad + 1;
+ if (quad == 6)
+ quad = 1;
+ h.y = sidelength - h.x;
+ h.z = h.x - sidelength;
+ h.x = 0;
+ } else if (h.x == sidelength) {
+ quad += 5;
+ h.y = -h.z;
+ h.x = 0;
+ }
+ } else if (quad >= 6) {
+ if (h.z == 0 && h.x == sidelength) {
+ /* south pole */
+ quad = 11;
+ h.x = 0;
+ h.y = 0;
+ h.z = 0;
+ } else if (h.x == sidelength) {
+ quad = quad + 1;
+ if (quad == 11)
+ quad = 6;
+ h.x = h.y + sidelength;
+ h.y = 0;
+ h.z = -h.x;
+ } else if (h.y == -sidelength) {
+ quad -= 4;
+ h.y = 0;
+ h.z = -h.x;
+ }
+ }
+ di->x = h.x;
+ di->y = -h.z;
+
+ g->quad = quad;
+ return quad;
+ }
+
+ static
+ int isea_ptdi(struct isea_dgg *g, int tri, struct isea_pt *pt,
+ struct isea_pt *di) {
+ struct isea_pt v;
+ int quad;
+
+ v = *pt;
+ quad = isea_ptdd(tri, &v);
+ quad = isea_dddi(g, quad, &v, di);
+ return quad;
+ }
+
+ /* q2di to seqnum */
+ static
+ int isea_disn(struct isea_dgg *g, int quad, struct isea_pt *di) {
+ int sidelength;
+ int sn, height;
+ int hexes;
+
+ if (quad == 0) {
+ g->serial = 1;
+ return g->serial;
+ }
+ /* hexes in a quad */
+ hexes = (int) (pow(static_cast<double>(g->aperture), g->resolution) + 0.5);
+ if (quad == 11) {
+ g->serial = 1 + 10 * hexes + 1;
+ return g->serial;
+ }
+ if (g->aperture == 3 && g->resolution % 2 == 1) {
+ height = (int) (pow(static_cast<double>(g->aperture), (g->resolution - 1) / 2.0));
+ sn = ((int) di->x) * height;
+ sn += ((int) di->y) / height;
+ sn += (quad - 1) * hexes;
+ sn += 2;
+ } else {
+ sidelength = (int) (pow(static_cast<double>(g->aperture), g->resolution / 2.0) + 0.5);
+ sn = (quad - 1) * hexes + sidelength * di->x + di->y + 2;
+ }
+
+ g->serial = sn;
+ return sn;
+ }
+
+ /* TODO just encode the quad in the d or i coordinate
+ * quad is 0-11, which can be four bits.
+ * d' = d << 4 + q, d = d' >> 4, q = d' & 0xf
+ */
+ /* convert a q2di to global hex coord */
+ static
+ int isea_hex(struct isea_dgg *g, int tri,
+ struct isea_pt *pt, struct isea_pt *hex) {
+ struct isea_pt v;
+ int sidelength;
+ int d, i, x, y, quad;
+
+ quad = isea_ptdi(g, tri, pt, &v);
+
+ hex->x = ((int)v.x << 4) + quad;
+ hex->y = v.y;
+
+ return 1;
+
+ d = v.x;
+ i = v.y;
+
+ /* Aperture 3 odd resolutions */
+ if (g->aperture == 3 && g->resolution % 2 != 0) {
+ int offset = (int)(pow(3.0, g->resolution - 1) + 0.5);
+
+ d += offset * ((g->quad-1) % 5);
+ i += offset * ((g->quad-1) % 5);
+
+ if (quad == 0) {
+ d = 0;
+ i = offset;
+ } else if (quad == 11) {
+ d = 2 * offset;
+ i = 0;
+ } else if (quad > 5) {
+ d += offset;
+ }
+
+ x = (2*d - i) /3;
+ y = (2*i - d) /3;
+
+ hex->x = x + offset / 3;
+ hex->y = y + 2 * offset / 3;
+ return 1;
+ }
+
+ /* aperture 3 even resolutions and aperture 4 */
+ sidelength = (int) (pow(static_cast<double>(g->aperture), g->resolution / 2.0) + 0.5);
+ if (g->quad == 0) {
+ hex->x = 0;
+ hex->y = sidelength;
+ } else if (g->quad == 11) {
+ hex->x = sidelength * 2;
+ hex->y = 0;
+ } else {
+ hex->x = d + sidelength * ((g->quad-1) % 5);
+ if (g->quad > 5) hex->x += sidelength;
+ hex->y = i + sidelength * ((g->quad-1) % 5);
+ }
+
+ return 1;
+ }
+
+ static
+ struct isea_pt
+ isea_forward(struct isea_dgg *g, struct isea_geo *in)
+ {
+ int tri, downtri;
+ struct isea_pt out, coord;
+
+ tri = isea_transform(g, in, &out);
+
+ downtri = (((tri - 1) / 5) % 2 == 1);
+ boost::ignore_unused(downtri);
+
+ if (g->output == ISEA_PLANE) {
+ isea_tri_plane(tri, &out, g->radius);
+ return out;
+ }
+
+ /* convert to isea standard triangle size */
+ out.x = out.x / g->radius * ISEA_SCALE;
+ out.y = out.y / g->radius * ISEA_SCALE;
+ out.x += 0.5;
+ out.y += 2.0 * .14433756729740644112;
+
+ switch (g->output) {
+ case ISEA_PROJTRI:
+ /* nothing to do, already in projected triangle */
+ break;
+ case ISEA_VERTEX2DD:
+ g->quad = isea_ptdd(tri, &out);
+ break;
+ case ISEA_Q2DD:
+ /* Same as above, we just don't print as much */
+ g->quad = isea_ptdd(tri, &out);
+ break;
+ case ISEA_Q2DI:
+ g->quad = isea_ptdi(g, tri, &out, &coord);
+ return coord;
+ break;
+ case ISEA_SEQNUM:
+ isea_ptdi(g, tri, &out, &coord);
+ /* disn will set g->serial */
+ isea_disn(g, g->quad, &coord);
+ return coord;
+ break;
+ case ISEA_HEX:
+ isea_hex(g, tri, &out, &coord);
+ return coord;
+ break;
+ }
+
+ return out;
+ }
+ /*
+ * Proj 4 integration code follows
+ */
+
+ struct par_isea
+ {
+ struct isea_dgg dgg;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_isea_spheroid : public base_t_f<base_isea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_isea m_proj_parm;
+
+ inline base_isea_spheroid(const Parameters& par)
+ : base_t_f<base_isea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward)
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ struct isea_pt out;
+ struct isea_geo in;
+
+ in.lon = lp_lon;
+ in.lat = lp_lat;
+
+ isea_dgg copy = this->m_proj_parm.dgg;
+ out = isea_forward(&copy, &in);
+
+ xy_x = out.x;
+ xy_y = out.y;
+ }
+
+ static inline std::string get_name()
+ {
+ return "isea_spheroid";
+ }
+
+ };
+
+ // Icosahedral Snyder Equal Area
+ template <typename Parameters>
+ void setup_isea(Parameters& par, par_isea& proj_parm)
+ {
+ std::string opt;
+
+ isea_grid_init(&proj_parm.dgg);
+
+ proj_parm.dgg.output = ISEA_PLANE;
+ /* proj_parm.dgg.radius = par.a; / * otherwise defaults to 1 */
+ /* calling library will scale, I think */
+
+ opt = pj_param(par.params, "sorient").s;
+ if (! opt.empty()) {
+ if (opt == std::string("isea")) {
+ isea_orient_isea(&proj_parm.dgg);
+ } else if (opt == std::string("pole")) {
+ isea_orient_pole(&proj_parm.dgg);
+ } else {
+ throw proj_exception(-34);
+ }
+ }
+
+ if (pj_param(par.params, "tazi").i) {
+ proj_parm.dgg.o_az = pj_param(par.params, "razi").f;
+ }
+
+ if (pj_param(par.params, "tlon_0").i) {
+ proj_parm.dgg.o_lon = pj_param(par.params, "rlon_0").f;
+ }
+
+ if (pj_param(par.params, "tlat_0").i) {
+ proj_parm.dgg.o_lat = pj_param(par.params, "rlat_0").f;
+ }
+
+ if (pj_param(par.params, "taperture").i) {
+ proj_parm.dgg.aperture = pj_param(par.params, "iaperture").i;
+ }
+
+ if (pj_param(par.params, "tresolution").i) {
+ proj_parm.dgg.resolution = pj_param(par.params, "iresolution").i;
+ }
+
+ opt = pj_param(par.params, "smode").s;
+ if (! opt.empty()) {
+ if (opt == std::string("plane")) {
+ proj_parm.dgg.output = ISEA_PLANE;
+ } else if (opt == std::string("di")) {
+ proj_parm.dgg.output = ISEA_Q2DI;
+ }
+ else if (opt == std::string("dd")) {
+ proj_parm.dgg.output = ISEA_Q2DD;
+ }
+ else if (opt == std::string("hex")) {
+ proj_parm.dgg.output = ISEA_HEX;
+ }
+ else {
+ /* TODO verify error code. Possibly eliminate magic */
+ throw proj_exception(-34);
+ }
+ }
+
+ if (pj_param(par.params, "trescale").i) {
+ proj_parm.dgg.radius = ISEA_SCALE;
+ }
+
+ if (pj_param(par.params, "tresolution").i) {
+ proj_parm.dgg.resolution = pj_param(par.params, "iresolution").i;
+ } else {
+ proj_parm.dgg.resolution = 4;
+ }
+
+ if (pj_param(par.params, "taperture").i) {
+ proj_parm.dgg.aperture = pj_param(par.params, "iaperture").i;
+ } else {
+ proj_parm.dgg.aperture = 3;
+ }
+ }
+
+ }} // namespace detail::isea
+ #endif // doxygen
+
+ /*!
+ \brief Icosahedral Snyder Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Spheroid
+ \par Projection parameters
+ - orient (string)
+ - azi: Azimuth (or Gamma) (degrees)
+ - lon_0: Central meridian (degrees)
+ - lat_0: Latitude of origin (degrees)
+ - aperture (integer)
+ - resolution (integer)
+ - mode (string)
+ - rescale
+ \par Example
+ \image html ex_isea.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct isea_spheroid : public detail::isea::base_isea_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline isea_spheroid(const Parameters& par) : detail::isea::base_isea_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::isea::setup_isea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class isea_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<isea_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void isea_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("isea", new isea_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/krovak.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/krovak.hpp
new file mode 100644
index 0000000000..a0eb26a536
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/krovak.hpp
@@ -0,0 +1,342 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the krovak (Krovak) projection.
+// Definition: http://www.ihsenergy.com/epsg/guid7.html#1.4.3
+// Author: Thomas Flemming, tf@ttqv.com
+// Copyright (c) 2001, Thomas Flemming, tf@ttqv.com
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "krovak_ellipsoid";
+ }
+
+ };
+
+ // 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 */
+ }
+
+ }} // 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
+ - Ellipsoid
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ - lat_0: Latitude of origin
+ - lon_0: Central meridian
+ - k: Scale factor on the pseudo standard parallel
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/labrd.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/labrd.hpp
new file mode 100644
index 0000000000..05c1a35349
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/labrd.hpp
@@ -0,0 +1,245 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(e_forward)
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(e_inverse) ellipsoid & spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "labrd_ellipsoid";
+ }
+
+ };
+
+ // 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;
+ }
+
+ }} // 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 Projection parameters
+ - no_rot: No rotation (boolean)
+ - azi: Azimuth (or Gamma) (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/laea.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/laea.hpp
new file mode 100644
index 0000000000..06b2a025a1
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/laea.hpp
@@ -0,0 +1,414 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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_auth.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 = geometry::math::half_pi<double>() + lp_lat;
+ q = this->m_proj_parm.qp - q;
+ break;
+ case S_POLE:
+ b = lp_lat - geometry::math::half_pi<double>();
+ 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;
+ }
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "laea_ellipsoid";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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 = geometry::math::half_pi<double>() - lp_lat;
+ break;
+ case S_POLE:
+ lp_lat -= geometry::math::half_pi<double>();
+ break;
+ }
+ lp_lon = (xy_y == 0. && (this->m_proj_parm.mode == EQUIT || this->m_proj_parm.mode == OBLIQ)) ?
+ 0. : atan2(xy_x, xy_y);
+ }
+
+ static inline std::string get_name()
+ {
+ return "laea_spheroid";
+ }
+
+ };
+
+ // Lambert Azimuthal Equal Area
+ template <typename Parameters>
+ void setup_laea(Parameters& par, par_laea& proj_parm)
+ {
+ double t;
+
+ if (fabs((t = fabs(par.phi0)) - geometry::math::half_pi<double>()) < 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;
+ }
+ } else {
+ if (proj_parm.mode == OBLIQ) {
+ proj_parm.sinb1 = sin(par.phi0);
+ proj_parm.cosb1 = cos(par.phi0);
+ }
+ }
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/lagrng.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/lagrng.hpp
new file mode 100644
index 0000000000..4bf8ed1de2
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/lagrng.hpp
@@ -0,0 +1,172 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) < 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;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "lagrng_spheroid";
+ }
+
+ };
+
+ // 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.;
+ }
+
+ }} // 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
+ \par Projection parameters
+ - W (real)
+ - lat_1: Latitude of first standard parallel (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/larr.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/larr.hpp
new file mode 100644
index 0000000000..95a8240865
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/larr.hpp
@@ -0,0 +1,141 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "larr_spheroid";
+ }
+
+ };
+
+ // Larrivee
+ template <typename Parameters>
+ void setup_larr(Parameters& par)
+ {
+ 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LARR_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/lask.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/lask.hpp
new file mode 100644
index 0000000000..7a30815a30
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/lask.hpp
@@ -0,0 +1,155 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "lask_spheroid";
+ }
+
+ };
+
+ // Laskowski
+ template <typename Parameters>
+ void setup_lask(Parameters& par)
+ {
+ 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LASK_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/latlong.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/latlong.hpp
new file mode 100644
index 0000000000..2118f5f4e8
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/latlong.hpp
@@ -0,0 +1,283 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Stub projection implementation for lat/long coordinates. We
+// don't actually change the coordinates, but we want proj=latlong
+// to act sort of like a projection.
+// Author: Frank Warmerdam, warmerdam@pobox.com
+// Copyright (c) 2000, Frank Warmerdam
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(forward)
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(inverse)
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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_par.a;
+ lp_lon = xy_x * this->m_par.a;
+ }
+
+ static inline std::string get_name()
+ {
+ return "latlong_other";
+ }
+
+ };
+
+ // Lat/long (Geodetic)
+ template <typename Parameters>
+ void setup_lonlat(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ }
+
+ // Lat/long (Geodetic alias)
+ template <typename Parameters>
+ void setup_latlon(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ }
+
+ // Lat/long (Geodetic alias)
+ template <typename Parameters>
+ void setup_latlong(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ }
+
+ // Lat/long (Geodetic alias)
+ template <typename Parameters>
+ void setup_longlat(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ }
+
+ }} // 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 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 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 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 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/lcc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/lcc.hpp
new file mode 100644
index 0000000000..342551d608
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/lcc.hpp
@@ -0,0 +1,267 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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_phi2.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp>
+
+#include <boost/geometry/extensions/gis/projections/epsg_traits.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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;
+
+ 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) {}
+
+ // FORWARD(e_forward) ellipsoid & spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) < 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) );
+ }
+
+ // INVERSE(e_inverse) ellipsoid & spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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)) - geometry::math::half_pi<double>();
+ lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n;
+ } else {
+ lp_lon = 0.;
+ lp_lat = this->m_proj_parm.n > 0. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>();
+ }
+ }
+
+ // SPECIAL(fac)
+ #ifdef SPECIAL_FACTORS_NOT_CONVERTED
+ inline void fac(Geographic lp, Factors &fac) const
+ {
+ double rho;
+ if (fabs(fabs(lp_lat) - geometry::math::half_pi<double>()) < 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
+
+ static inline std::string get_name()
+ {
+ return "lcc_ellipsoid";
+ }
+
+ };
+
+ // 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) - geometry::math::half_pi<double>()) < 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) - geometry::math::half_pi<double>()) < EPS10) ? 0. :
+ proj_parm.c * pow(tan(FORTPI + .5 * par.phi0), -proj_parm.n);
+ }
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ - lat_2: Latitude of second standard parallel (degrees)
+ - lat_0: Latitude of origin
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LCC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/lcca.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/lcca.hpp
new file mode 100644
index 0000000000..394e4b9e78
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/lcca.hpp
@@ -0,0 +1,206 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/core/ignore_unused.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 projections
+{
+ #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;
+ };
+
+ static double /* func to compute dr */
+ fS(double S, double C) {
+ return(S * ( 1. + S * S * C));
+ }
+ static 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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) );
+ }
+
+ // INVERSE(e_inverse) ellipsoid & spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "lcca_ellipsoid";
+ }
+
+ };
+
+ // Lambert Conformal Conic Alternative
+ template <typename Parameters>
+ void setup_lcca(Parameters& par, par_lcca& proj_parm)
+ {
+ boost::ignore_unused(fSp);
+ double s2p0, N0, R0, tan0, tan20;
+
+ if (!pj_enfn(par.es, proj_parm.en)) throw proj_exception(0);
+ 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);
+ boost::ignore_unused(tan20);
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_0: Latitude of origin
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/loxim.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/loxim.hpp
new file mode 100644
index 0000000000..0deb112e48
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/loxim.hpp
@@ -0,0 +1,178 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) < EPS)
+ xy_x = 0.;
+ else
+ xy_x = lp_lon * xy_y / log( tan(xy_x) / this->m_proj_parm.tanphi1 );
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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.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) - geometry::math::half_pi<double>()) < EPS)
+ lp_lon = 0.;
+ else
+ lp_lon = xy_x * log( tan(lp_lon) / this->m_proj_parm.tanphi1 ) / xy_y ;
+ }
+
+ static inline std::string get_name()
+ {
+ return "loxim_spheroid";
+ }
+
+ };
+
+ // 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.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 Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/lsat.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/lsat.hpp
new file mode 100644
index 0000000000..188e3f8ef4
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/lsat.hpp
@@ -0,0 +1,312 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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>
+ static void
+ seraz0(double lam, double mult, Parameters& par, par_lsat& proj_parm) {
+ double sdsq, h, s, fc, sd, sq, d__1;
+
+ lam *= geometry::math::d2r<double>();
+ 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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 > geometry::math::half_pi<double>())
+ lp_lat = geometry::math::half_pi<double>();
+ else if (lp_lat < -geometry::math::half_pi<double>())
+ lp_lat = -geometry::math::half_pi<double>();
+ lampp = lp_lat >= 0. ? geometry::math::half_pi<double>() : 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>());
+ 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 = geometry::math::half_pi<double>();
+ }
+ 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;
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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 -= geometry::math::half_pi<double>() * (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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "lsat_ellipsoid";
+ }
+
+ };
+
+ // 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 = geometry::math::d2r<double>() * 128.87 - geometry::math::two_pi<double>() / 251. * path;
+ proj_parm.p22 = 103.2669323;
+ alf = geometry::math::d2r<double>() * 99.092;
+ } else {
+ par.lam0 = geometry::math::d2r<double>() * 129.3 - geometry::math::two_pi<double>() / 233. * path;
+ proj_parm.p22 = 98.8841202;
+ alf = geometry::math::d2r<double>() * 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 = geometry::math::pi<double>() * (1. / 248. + .5161290322580645);
+ proj_parm.rlm2 = proj_parm.rlm + geometry::math::two_pi<double>();
+ 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.;
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lsat (integer)
+ - path (integer)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/mbt_fps.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/mbt_fps.hpp
new file mode 100644
index 0000000000..a155e62e20
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/mbt_fps.hpp
@@ -0,0 +1,171 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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 = 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "mbt_fps_spheroid";
+ }
+
+ };
+
+ // McBryde-Thomas Flat-Pole Sine (No. 2)
+ template <typename Parameters>
+ void setup_mbt_fps(Parameters& par)
+ {
+ par.es = 0;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/mbtfpp.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/mbtfpp.hpp
new file mode 100644
index 0000000000..f0399a3eab
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/mbtfpp.hpp
@@ -0,0 +1,166 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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.) ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ } 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.) ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ } else
+ lp_lat = asin(lp_lat);
+ }
+
+ static inline std::string get_name()
+ {
+ return "mbtfpp_spheroid";
+ }
+
+ };
+
+ // McBride-Thomas Flat-Polar Parabolic
+ template <typename Parameters>
+ void setup_mbtfpp(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MBTFPP_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/mbtfpq.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/mbtfpq.hpp
new file mode 100644
index 0000000000..972a08bf8f
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/mbtfpq.hpp
@@ -0,0 +1,181 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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 = -geometry::math::pi<double>(); }
+ else { t = 1.; lp_lat = geometry::math::pi<double>(); }
+ } 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ else
+ lp_lat = asin(lp_lat);
+ }
+
+ static inline std::string get_name()
+ {
+ return "mbtfpq_spheroid";
+ }
+
+ };
+
+ // McBryde-Thomas Flat-Polar Quartic
+ template <typename Parameters>
+ void setup_mbtfpq(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/merc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/merc.hpp
new file mode 100644
index 0000000000..815e8aff95
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/merc.hpp
@@ -0,0 +1,235 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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_phi2.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) <= 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));
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "merc_ellipsoid";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) <= EPS10) throw proj_exception();;
+ xy_x = this->m_par.k0 * lp_lon;
+ xy_y = this->m_par.k0 * log(tan(FORTPI + .5 * lp_lat));
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = geometry::math::half_pi<double>() - 2. * atan(exp(-xy_y / this->m_par.k0));
+ lp_lon = xy_x / this->m_par.k0;
+ }
+
+ static inline std::string get_name()
+ {
+ return "merc_spheroid";
+ }
+
+ };
+
+ // 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 >= geometry::math::half_pi<double>()) throw proj_exception(-24);
+ }
+ if (par.es) { /* ellipsoid */
+ if (is_phits)
+ par.k0 = pj_msfn(sin(phits), cos(phits), par.es);
+ } else { /* sphere */
+ if (is_phits)
+ par.k0 = cos(phits);
+ }
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \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
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MERC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/mill.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/mill.hpp
new file mode 100644
index 0000000000..a78e76dfec
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/mill.hpp
@@ -0,0 +1,146 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "mill_spheroid";
+ }
+
+ };
+
+ // Miller Cylindrical
+ template <typename Parameters>
+ void setup_mill(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MILL_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/mod_ster.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/mod_ster.hpp
new file mode 100644
index 0000000000..02daa00395
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/mod_ster.hpp
@@ -0,0 +1,491 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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/aasincos.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_zpoly1.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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((geometry::math::half_pi<double>() + lp_lat) * .5) *
+ pow((1. - esphi) / (1. + esphi), this->m_par.e * .5)) - geometry::math::half_pi<double>();
+ 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;
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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((geometry::math::half_pi<double>() + chi) * .5) *
+ pow((1. + esphi) / (1. - esphi), this->m_par.e * .5)) - geometry::math::half_pi<double>() - 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "mod_ster_ellipsoid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_mod_ster& proj_parm) /* general initialization */
+ {
+ double esphi, chio;
+
+ if (par.es) {
+ esphi = par.e * sin(par.phi0);
+ chio = 2. * atan(tan((geometry::math::half_pi<double>() + par.phi0) * .5) *
+ pow((1. - esphi) / (1. + esphi), par.e * .5)) - geometry::math::half_pi<double>();
+ } else
+ chio = par.phi0;
+ proj_parm.schio = sin(chio);
+ proj_parm.cchio = cos(chio);
+ }
+
+
+ // 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 = geometry::math::d2r<double>() * 20.;
+ par.phi0 = geometry::math::d2r<double>() * 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 = geometry::math::d2r<double>() * -165.;
+ par.phi0 = geometry::math::d2r<double>() * -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 = geometry::math::d2r<double>() * -96.;
+ par.phi0 = geometry::math::d2r<double>() * -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 = geometry::math::d2r<double>() * -152.;
+ par.phi0 = geometry::math::d2r<double>() * 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 = geometry::math::d2r<double>() * -120.;
+ par.phi0 = geometry::math::d2r<double>() * 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
+ - Azimuthal (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
+ - Azimuthal (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
+ - Azimuthal (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
+ - Azimuthal (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
+ - Azimuthal (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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/moll.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/moll.hpp
new file mode 100644
index 0000000000..db98ffce09
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/moll.hpp
@@ -0,0 +1,269 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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.) ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "moll_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_moll& proj_parm, double p)
+ {
+ double r, sp, p2 = p + p;
+
+ par.es = 0;
+ sp = sin(p);
+ r = sqrt(geometry::math::two_pi<double>() * sp / (p2 + sin(p2)));
+ proj_parm.C_x = 2. * r / geometry::math::pi<double>();
+ proj_parm.C_y = r / sp;
+ proj_parm.C_p = p2 + sin(p2);
+ }
+
+
+ // Mollweide
+ template <typename Parameters>
+ void setup_moll(Parameters& par, par_moll& proj_parm)
+ {
+ setup(par, proj_parm, geometry::math::half_pi<double>());
+ }
+
+ // Wagner IV
+ template <typename Parameters>
+ void setup_wag4(Parameters& par, par_moll& proj_parm)
+ {
+ setup(par, proj_parm, geometry::math::pi<double>()/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;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MOLL_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/natearth.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/natearth.hpp
new file mode 100644
index 0000000000..157e268cde
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/natearth.hpp
@@ -0,0 +1,205 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// The Natural Earth projection was designed by Tom Patterson, US National Park
+// Service, in 2007, using Flex Projector. The shape of the original projection
+// was defined at every 5 degrees and piece-wise cubic spline interpolation was
+// used to compute the complete graticule.
+// The code here uses polynomial functions instead of cubic splines and
+// is therefore much simpler to program. The polynomial approximation was
+// developed by Bojan Savric, in collaboration with Tom Patterson and Bernhard
+// Jenny, Institute of Cartography, ETH Zurich. It slightly deviates from
+// Patterson's original projection by adding additional curvature to meridians
+// where they meet the horizontal pole line. This improvement is by intention
+// and designed in collaboration with Tom Patterson.
+// Port to PROJ.4 by Bernhard Jenny, 6 June 2011
+
+// 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/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 projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace natearth
+ {
+
+ static const double A0 = 0.8707;
+ static const double A1 = -0.131979;
+ static const double A2 = -0.013791;
+ static const double A3 = 0.003971;
+ static const double A4 = -0.001529;
+ static const double B0 = 1.007226;
+ static const double B1 = 0.015085;
+ static const double B2 = -0.044475;
+ static const double B3 = 0.028874;
+ static const double B4 = -0.005916;
+ static const double C0 = B0;
+ static const double C1 = (3 * B1);
+ static const double C2 = (7 * B2);
+ static const double C3 = (9 * B3);
+ static const double C4 = (11 * B4);
+ static const double EPS = 1e-11;
+ static const double MAX_Y = (0.8707 * 0.52 * geometry::math::pi<double>());
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_natearth_spheroid : public base_t_fi<base_natearth_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_natearth_spheroid(const Parameters& par)
+ : base_t_fi<base_natearth_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double phi2, phi4;
+
+ phi2 = lp_lat * lp_lat;
+ phi4 = phi2 * phi2;
+ xy_x = lp_lon * (A0 + phi2 * (A1 + phi2 * (A2 + phi4 * phi2 * (A3 + phi2 * A4))));
+ xy_y = lp_lat * (B0 + phi2 * (B1 + phi4 * (B2 + B3 * phi2 + B4 * phi4)));
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double yc, tol, y2, y4, f, fder;
+
+ /* make sure y is inside valid range */
+ if (xy_y > MAX_Y) {
+ xy_y = MAX_Y;
+ } else if (xy_y < -MAX_Y) {
+ xy_y = -MAX_Y;
+ }
+
+ /* latitude */
+ yc = xy_y;
+ for (;;) { /* Newton-Raphson */
+ y2 = yc * yc;
+ y4 = y2 * y2;
+ f = (yc * (B0 + y2 * (B1 + y4 * (B2 + B3 * y2 + B4 * y4)))) - xy_y;
+ fder = C0 + y2 * (C1 + y4 * (C2 + C3 * y2 + C4 * y4));
+ yc -= tol = f / fder;
+ if (fabs(tol) < EPS) {
+ break;
+ }
+ }
+ lp_lat = yc;
+
+ /* longitude */
+ y2 = yc * yc;
+ lp_lon = xy_x / (A0 + y2 * (A1 + y2 * (A2 + y2 * y2 * y2 * (A3 + y2 * A4))));
+ }
+
+ static inline std::string get_name()
+ {
+ return "natearth_spheroid";
+ }
+
+ };
+
+ // Natural Earth
+ template <typename Parameters>
+ void setup_natearth(Parameters& par)
+ {
+ par.es = 0;
+ }
+
+ }} // namespace detail::natearth
+ #endif // doxygen
+
+ /*!
+ \brief Natural Earth 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_natearth.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct natearth_spheroid : public detail::natearth::base_natearth_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline natearth_spheroid(const Parameters& par) : detail::natearth::base_natearth_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::natearth::setup_natearth(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class natearth_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<natearth_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void natearth_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("natearth", new natearth_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/nell.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/nell.hpp
new file mode 100644
index 0000000000..b27d36165d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/nell.hpp
@@ -0,0 +1,162 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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)));
+ }
+
+ static inline std::string get_name()
+ {
+ return "nell_spheroid";
+ }
+
+ };
+
+ // Nell
+ template <typename Parameters>
+ void setup_nell(Parameters& par)
+ {
+ par.es = 0;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NELL_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/nell_h.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/nell_h.hpp
new file mode 100644
index 0000000000..95eb158b9c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/nell_h.hpp
@@ -0,0 +1,164 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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));
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ lp_lon = 2. * xy_x;
+ } else
+ lp_lon = 2. * xy_x / (1. + cos(lp_lat));
+ }
+
+ static inline std::string get_name()
+ {
+ return "nell_h_spheroid";
+ }
+
+ };
+
+ // Nell-Hammer
+ template <typename Parameters>
+ void setup_nell_h(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NELL_H_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/nocol.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/nocol.hpp
new file mode 100644
index 0000000000..bbb1fb4fd9
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/nocol.hpp
@@ -0,0 +1,170 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) < EPS) {
+ xy_x = lp_lon * cos(lp_lat);
+ xy_y = geometry::math::half_pi<double>() * sin(lp_lat);
+ } else if (fabs(fabs(lp_lat) - geometry::math::half_pi<double>()) < EPS) {
+ xy_x = 0;
+ xy_y = lp_lat;
+ } else {
+ double tb, c, d, m, n, r2, sp;
+
+ tb = geometry::math::half_pi<double>() / lp_lon - lp_lon / geometry::math::half_pi<double>();
+ c = lp_lat / geometry::math::half_pi<double>();
+ 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 = geometry::math::half_pi<double>() * ( m + (lp_lon < 0. ? -xy_x : xy_x));
+ xy_y = sqrt(n * n - (sp * sp / r2 + d * sp - 1.) /
+ (1. + 1./r2));
+ xy_y = geometry::math::half_pi<double>() * ( n + (lp_lat < 0. ? xy_y : -xy_y ));
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "nocol_spheroid";
+ }
+
+ };
+
+ // Nicolosi Globular
+ template <typename Parameters>
+ void setup_nicol(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NOCOL_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/nsper.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/nsper.hpp
new file mode 100644
index 0000000000..31af31a979
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/nsper.hpp
@@ -0,0 +1,329 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "nsper_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_nsper& proj_parm)
+ {
+ if ((proj_parm.height = pj_param(par.params, "dh").f) <= 0.) throw proj_exception(-30);
+ if (fabs(fabs(par.phi0) - geometry::math::half_pi<double>()) < 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.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 * geometry::math::d2r<double>();
+ gamma = pj_param(par.params, "dazi").f * geometry::math::d2r<double>();
+ 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
+ \par Projection parameters
+ - h: Height
+ \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
+ \par Projection parameters
+ - tilt: Tilt, or Omega (real)
+ - azi: Azimuth (or Gamma) (real)
+ - h: Height
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/nzmg.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/nzmg.hpp
new file mode 100644
index 0000000000..80e4a17f86
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/nzmg.hpp
@@ -0,0 +1,210 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the nzmg (New Zealand Map Grid) projection.
+// Very loosely based upon DMA code by Bradford W. Drew
+// Author: Gerald Evenden
+// Copyright (c) 1995, Gerald Evenden
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "nzmg_ellipsoid";
+ }
+
+ };
+
+ // 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 = geometry::math::d2r<double>() * 173.;
+ par.phi0 = geometry::math::d2r<double>() * -41.;
+ par.x0 = 2510000.;
+ par.y0 = 6023150.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NZMG_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/ob_tran.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/ob_tran.hpp
new file mode 100644
index 0000000000..1769a1fd5c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/ob_tran.hpp
@@ -0,0 +1,355 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.hpp>
+#include <boost/shared_ptr.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 projections
+{
+
+ 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) {}
+
+ // FORWARD(o_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(o_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "ob_tran_oblique";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(t_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(t_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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));
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "ob_tran_transverse";
+ }
+
+ };
+
+ // 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)
+ {
+ double phip;
+ Parameters pj;
+
+ /* get name of projection to be translated */
+ pj.name = pj_param(par.params, "so_proj").s;
+ /* 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.;
+
+ if (create)
+ {
+ factory<Geographic, Cartesian, Parameters> fac;
+ 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) - geometry::math::half_pi<double>()) <= TOL ||
+ fabs(fabs(alpha) - geometry::math::half_pi<double>()) <= TOL)
+ */
+ if (fabs(fabs(phic) - geometry::math::half_pi<double>()) <= 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 - geometry::math::half_pi<double>()) <= TOL ||
+ fabs(fabs(phi2) - geometry::math::half_pi<double>()) <= 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);
+ } else { /* transverse */
+ }
+ // 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
+ \par Projection parameters
+ - o_proj (string)
+ - Plus projection parameters
+ - o_lat_p (degrees)
+ - o_lon_p (degrees)
+ - New pole
+ - o_alpha: Alpha (degrees)
+ - o_lon_c (degrees)
+ - o_lat_c (degrees)
+ - o_lon_1 (degrees)
+ - o_lat_1: Latitude of first standard parallel (degrees)
+ - o_lon_2 (degrees)
+ - o_lat_2: Latitude of second standard parallel (degrees)
+ \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
+ \par Projection parameters
+ - o_proj (string)
+ - Plus projection parameters
+ - o_lat_p (degrees)
+ - o_lon_p (degrees)
+ - New pole
+ - o_alpha: Alpha (degrees)
+ - o_lon_c (degrees)
+ - o_lat_c (degrees)
+ - o_lon_1 (degrees)
+ - o_lat_1: Latitude of first standard parallel (degrees)
+ - o_lon_2 (degrees)
+ - o_lat_2: Latitude of second standard parallel (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/ocea.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/ocea.hpp
new file mode 100644
index 0000000000..67f21ef857
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/ocea.hpp
@@ -0,0 +1,207 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 += geometry::math::pi<double>();
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "ocea_spheroid";
+ }
+
+ };
+
+ // 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 + geometry::math::half_pi<double>();
+ 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.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
+ - Spheroid
+ \par Projection parameters
+ - lonc: Longitude (only used if alpha (or gamma) is specified) (degrees)
+ - alpha: Alpha (degrees)
+ - lat_1: Latitude of first standard parallel (degrees)
+ - lat_2: Latitude of second standard parallel (degrees)
+ - lon_1 (degrees)
+ - lon_2 (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/oea.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/oea.hpp
new file mode 100644
index 0000000000..4a2cf781f2
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/oea.hpp
@@ -0,0 +1,196 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "oea_spheroid";
+ }
+
+ };
+
+ // 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.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
+ \par Projection parameters
+ - n (real)
+ - m (real)
+ - theta: Theta (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_OEA_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/omerc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/omerc.hpp
new file mode 100644
index 0000000000..eb59a58913
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/omerc.hpp
@@ -0,0 +1,326 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Copyright (c) 2003, 2006 Gerald I. Evenden
+
+// 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/geometry/util/math.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_phi2.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace omerc
+ {
+
+ static const double TOL = 1.e-7;
+ static const double EPS = 1.e-10;
+
+ 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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) > 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);
+ if(fabs(temp) < TOL) {
+ u = this->m_proj_parm.A * lp_lon;
+ } else {
+ u = 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;
+ }
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ } 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));
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "omerc_ellipsoid";
+ }
+
+ };
+
+ // 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=0,
+ gamma0, lamc=0, lam1=0, lam2=0, phi1=0, phi2=0, alpha_c=0.0;
+ 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) != 0)
+ alpha_c = pj_param(par.params, "ralpha").f;
+ if ((gam = pj_param(par.params, "tgamma").i) != 0)
+ gamma = pj_param(par.params, "rgamma").f;
+ if (alp || gam) {
+ lamc = pj_param(par.params, "rlonc").f;
+ no_off =
+ /* For libproj4 compatability */
+ pj_param(par.params, "tno_off").i
+ /* for backward compatibility */
+ || pj_param(par.params, "tno_uoff").i;
+ if( no_off )
+ {
+ /* Mark the parameter as used, so that the pj_get_def() return them */
+ pj_param(par.params, "sno_uoff");
+ pj_param(par.params, "sno_off");
+ }
+ } 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 - geometry::math::half_pi<double>()) <= TOL ||
+ fabs(fabs(par.phi0) - geometry::math::half_pi<double>()) <= TOL ||
+ fabs(fabs(phi2) - geometry::math::half_pi<double>()) <= 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 - geometry::math::pi<double>()) <= TOL ||
+ fabs(fabs(par.phi0) - geometry::math::half_pi<double>()) <= 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) < -geometry::math::pi<double>())
+ lam2 -= geometry::math::two_pi<double>();
+ else if (con > geometry::math::pi<double>())
+ lam2 += geometry::math::two_pi<double>();
+ 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));
+ }
+
+ }} // 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
+ - Ellipsoid
+ \par Projection parameters
+ - no_rot: No rotation
+ - alpha: Alpha (degrees)
+ - gamma: Gamma (degrees)
+ - no_off: Only for compatibility with libproj, proj4 (string)
+ - lonc: Longitude (only used if alpha (or gamma) is specified) (degrees)
+ - lon_1 (degrees)
+ - lat_1: Latitude of first standard parallel (degrees)
+ - lon_2 (degrees)
+ - lat_2: Latitude of second standard parallel (degrees)
+ - no_uoff (string)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_OMERC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/ortho.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/ortho.hpp
new file mode 100644
index 0000000000..33e189c205
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/ortho.hpp
@@ -0,0 +1,228 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 > geometry::math::half_pi<double>()) throw proj_exception();;
+ xy_y = cosphi * coslam;
+ break;
+ }
+ xy_x = cosphi * sin(lp_lon);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>())
+ : atan2(xy_x, xy_y);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "ortho_spheroid";
+ }
+
+ };
+
+ // Orthographic
+ template <typename Parameters>
+ void setup_ortho(Parameters& par, par_ortho& proj_parm)
+ {
+ if (fabs(fabs(par.phi0) - geometry::math::half_pi<double>()) <= 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.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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ORTHO_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/poly.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/poly.hpp
new file mode 100644
index 0000000000..d37dcdbd2a
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/poly.hpp
@@ -0,0 +1,284 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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/impl/pj_msfn.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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));
+ }
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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.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);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "poly_ellipsoid";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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));
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "poly_spheroid";
+ }
+
+ };
+
+ // Polyconic (American)
+ template <typename Parameters>
+ void setup_poly(Parameters& par, par_poly& proj_parm)
+ {
+ if (par.es) {
+ if (!pj_enfn(par.es, proj_parm.en)) throw proj_exception(0);
+ proj_parm.ml0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en);
+ } else {
+ proj_parm.ml0 = -par.phi0;
+ }
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_POLY_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/putp2.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/putp2.hpp
new file mode 100644
index 0000000000..50d1607bfc
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/putp2.hpp
@@ -0,0 +1,173 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "putp2_spheroid";
+ }
+
+ };
+
+ // Putnins P2
+ template <typename Parameters>
+ void setup_putp2(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP2_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/putp3.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/putp3.hpp
new file mode 100644
index 0000000000..90ff9611aa
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/putp3.hpp
@@ -0,0 +1,206 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/core/ignore_unused.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "putp3_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_putp3& proj_parm)
+ {
+ boost::ignore_unused(proj_parm);
+ par.es = 0.;
+ }
+
+
+ // 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
+ - 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP3_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/putp4p.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/putp4p.hpp
new file mode 100644
index 0000000000..fa7ea3059c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/putp4p.hpp
@@ -0,0 +1,211 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/core/ignore_unused.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "putp4p_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_putp4p& proj_parm)
+ {
+ boost::ignore_unused(proj_parm);
+ par.es = 0.;
+ }
+
+
+ // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP4P_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/putp5.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/putp5.hpp
new file mode 100644
index 0000000000..854a0cc188
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/putp5.hpp
@@ -0,0 +1,208 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/core/ignore_unused.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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)));
+ }
+
+ static inline std::string get_name()
+ {
+ return "putp5_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_putp5& proj_parm)
+ {
+ boost::ignore_unused(proj_parm);
+ par.es = 0.;
+ }
+
+
+ // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP5_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/putp6.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/putp6.hpp
new file mode 100644
index 0000000000..41e9d26aa2
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/putp6.hpp
@@ -0,0 +1,234 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/core/ignore_unused.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "putp6_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_putp6& proj_parm)
+ {
+ boost::ignore_unused(proj_parm);
+ par.es = 0.;
+ }
+
+
+ // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP6_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/qsc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/qsc.hpp
new file mode 100644
index 0000000000..f96278b7ab
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/qsc.hpp
@@ -0,0 +1,502 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_QSC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_QSC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// This implements the Quadrilateralized Spherical Cube (QSC) projection.
+// Copyright (c) 2011, 2012 Martin Lambers <marlam@marlam.de>
+// The QSC projection was introduced in:
+// [OL76]
+// E.M. O'Neill and R.E. Laubscher, "Extended Studies of a Quadrilateralized
+// Spherical Cube Earth Data Base", Naval Environmental Prediction Research
+// Facility Tech. Report NEPRF 3-76 (CSC), May 1976.
+// The preceding shift from an ellipsoid to a sphere, which allows to apply
+// this projection to ellipsoids as used in the Ellipsoidal Cube Map model,
+// is described in
+// [LK12]
+// M. Lambers and A. Kolb, "Ellipsoidal Cube Maps for Accurate Rendering of
+// Planetary-Scale Terrain Data", Proc. Pacfic Graphics (Short Papers), Sep.
+// 2012
+// You have to choose one of the following projection centers,
+// corresponding to the centers of the six cube faces:
+// phi0 = 0.0, lam0 = 0.0 ("front" face)
+// phi0 = 0.0, lam0 = 90.0 ("right" face)
+// phi0 = 0.0, lam0 = 180.0 ("back" face)
+// phi0 = 0.0, lam0 = -90.0 ("left" face)
+// phi0 = 90.0 ("top" face)
+// phi0 = -90.0 ("bottom" face)
+// Other projection centers will not work!
+// In the projection code below, each cube face is handled differently.
+// See the computation of the face parameter in the ENTRY0(qsc) function
+// and the handling of different face values (FACE_*) in the forward and
+// inverse projections.
+// Furthermore, the projection is originally only defined for theta angles
+// between (-1/4 * PI) and (+1/4 * PI) on the current cube face. This area
+// of definition is named AREA_0 in the projection code below. The other
+// three areas of a cube face are handled by rotation of AREA_0.
+
+// 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/core/ignore_unused.hpp>
+#include <boost/geometry/util/math.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 projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace qsc
+ {
+
+ static const double EPS10 = 1.e-10;
+ static const int FACE_FRONT = 0;
+ static const int FACE_RIGHT = 1;
+ static const int FACE_BACK = 2;
+ static const int FACE_LEFT = 3;
+ static const int FACE_TOP = 4;
+ static const int FACE_BOTTOM = 5;
+ static const int AREA_0 = 0;
+ static const int AREA_1 = 1;
+ static const int AREA_2 = 2;
+ static const int AREA_3 = 3;
+
+ struct par_qsc
+ {
+ int face;
+ double a_squared;
+ double b;
+ double one_minus_f;
+ double one_minus_f_squared;
+ };
+
+ /* The six cube faces. */
+
+ /* The four areas on a cube face. AREA_0 is the area of definition,
+ * the other three areas are counted counterclockwise. */
+
+ /* Helper function for forward projection: compute the theta angle
+ * and determine the area number. */
+ static double
+ qsc_fwd_equat_face_theta(double phi, double y, double x, int *area) {
+ double theta;
+ if (phi < EPS10) {
+ *area = AREA_0;
+ theta = 0.0;
+ } else {
+ theta = atan2(y, x);
+ if (fabs(theta) <= FORTPI) {
+ *area = AREA_0;
+ } else if (theta > FORTPI && theta <= geometry::math::half_pi<double>() + FORTPI) {
+ *area = AREA_1;
+ theta -= geometry::math::half_pi<double>();
+ } else if (theta > geometry::math::half_pi<double>() + FORTPI || theta <= -(geometry::math::half_pi<double>() + FORTPI)) {
+ *area = AREA_2;
+ theta = (theta >= 0.0 ? theta - geometry::math::pi<double>() : theta + geometry::math::pi<double>());
+ } else {
+ *area = AREA_3;
+ theta += geometry::math::half_pi<double>();
+ }
+ }
+ return (theta);
+ }
+
+ /* Helper function: shift the longitude. */
+ static double
+ qsc_shift_lon_origin(double lon, double offset) {
+ double slon = lon + offset;
+ if (slon < -geometry::math::pi<double>()) {
+ slon += geometry::math::two_pi<double>();
+ } else if (slon > +geometry::math::pi<double>()) {
+ slon -= geometry::math::two_pi<double>();
+ }
+ return slon;
+ }
+
+ /* Forward projection, ellipsoid */
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_qsc_ellipsoid : public base_t_fi<base_qsc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_qsc m_proj_parm;
+
+ inline base_qsc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_qsc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward)
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double lat, lon;
+ double sinlat, coslat;
+ double sinlon, coslon;
+ double q = 0.0, r = 0.0, s = 0.0;
+ double theta, phi;
+ double t, mu, nu;
+ int area;
+
+ /* Convert the geodetic latitude to a geocentric latitude.
+ * This corresponds to the shift from the ellipsoid to the sphere
+ * described in [LK12]. */
+ if (this->m_par.es) {
+ lat = atan(this->m_proj_parm.one_minus_f_squared * tan(lp_lat));
+ } else {
+ lat = lp_lat;
+ }
+
+ /* Convert the input lat, lon into theta, phi as used by QSC.
+ * This depends on the cube face and the area on it.
+ * For the top and bottom face, we can compute theta and phi
+ * directly from phi, lam. For the other faces, we must use
+ * unit sphere cartesian coordinates as an intermediate step. */
+ lon = lp_lon;
+ if (this->m_proj_parm.face != FACE_TOP && this->m_proj_parm.face != FACE_BOTTOM) {
+ if (this->m_proj_parm.face == FACE_RIGHT) {
+ lon = qsc_shift_lon_origin(lon, +geometry::math::half_pi<double>());
+ } else if (this->m_proj_parm.face == FACE_BACK) {
+ lon = qsc_shift_lon_origin(lon, +geometry::math::pi<double>());
+ } else if (this->m_proj_parm.face == FACE_LEFT) {
+ lon = qsc_shift_lon_origin(lon, -geometry::math::half_pi<double>());
+ }
+ sinlat = sin(lat);
+ coslat = cos(lat);
+ sinlon = sin(lon);
+ coslon = cos(lon);
+ q = coslat * coslon;
+ r = coslat * sinlon;
+ s = sinlat;
+ }
+ if (this->m_proj_parm.face == FACE_FRONT) {
+ phi = acos(q);
+ theta = qsc_fwd_equat_face_theta(phi, s, r, &area);
+ } else if (this->m_proj_parm.face == FACE_RIGHT) {
+ phi = acos(r);
+ theta = qsc_fwd_equat_face_theta(phi, s, -q, &area);
+ } else if (this->m_proj_parm.face == FACE_BACK) {
+ phi = acos(-q);
+ theta = qsc_fwd_equat_face_theta(phi, s, -r, &area);
+ } else if (this->m_proj_parm.face == FACE_LEFT) {
+ phi = acos(-r);
+ theta = qsc_fwd_equat_face_theta(phi, s, q, &area);
+ } else if (this->m_proj_parm.face == FACE_TOP) {
+ phi = geometry::math::half_pi<double>() - lat;
+ if (lon >= FORTPI && lon <= geometry::math::half_pi<double>() + FORTPI) {
+ area = AREA_0;
+ theta = lon - geometry::math::half_pi<double>();
+ } else if (lon > geometry::math::half_pi<double>() + FORTPI || lon <= -(geometry::math::half_pi<double>() + FORTPI)) {
+ area = AREA_1;
+ theta = (lon > 0.0 ? lon - geometry::math::pi<double>() : lon + geometry::math::pi<double>());
+ } else if (lon > -(geometry::math::half_pi<double>() + FORTPI) && lon <= -FORTPI) {
+ area = AREA_2;
+ theta = lon + geometry::math::half_pi<double>();
+ } else {
+ area = AREA_3;
+ theta = lon;
+ }
+ } else /* this->m_proj_parm.face == FACE_BOTTOM */ {
+ phi = geometry::math::half_pi<double>() + lat;
+ if (lon >= FORTPI && lon <= geometry::math::half_pi<double>() + FORTPI) {
+ area = AREA_0;
+ theta = -lon + geometry::math::half_pi<double>();
+ } else if (lon < FORTPI && lon >= -FORTPI) {
+ area = AREA_1;
+ theta = -lon;
+ } else if (lon < -FORTPI && lon >= -(geometry::math::half_pi<double>() + FORTPI)) {
+ area = AREA_2;
+ theta = -lon - geometry::math::half_pi<double>();
+ } else {
+ area = AREA_3;
+ theta = (lon > 0.0 ? -lon + geometry::math::pi<double>() : -lon - geometry::math::pi<double>());
+ }
+ }
+
+ /* Compute mu and nu for the area of definition.
+ * For mu, see Eq. (3-21) in [OL76], but note the typos:
+ * compare with Eq. (3-14). For nu, see Eq. (3-38). */
+ mu = atan((12.0 / geometry::math::pi<double>()) * (theta + acos(sin(theta) * cos(FORTPI)) - geometry::math::half_pi<double>()));
+ t = sqrt((1.0 - cos(phi)) / (cos(mu) * cos(mu)) / (1.0 - cos(atan(1.0 / cos(theta)))));
+ /* nu = atan(t); We don't really need nu, just t, see below. */
+
+ /* Apply the result to the real area. */
+ if (area == AREA_1) {
+ mu += geometry::math::half_pi<double>();
+ } else if (area == AREA_2) {
+ mu += geometry::math::pi<double>();
+ } else if (area == AREA_3) {
+ mu += geometry::math::half_pi<double>() + geometry::math::pi<double>();
+ }
+
+ /* Now compute x, y from mu and nu */
+ /* t = tan(nu); */
+ xy_x = t * cos(mu);
+ xy_y = t * sin(mu);
+ boost::ignore_unused(nu);
+ }
+ /* Inverse projection, ellipsoid */
+
+ // INVERSE(e_inverse)
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double mu, nu, cosmu, tannu;
+ double tantheta, theta, cosphi, phi;
+ double t;
+ int area;
+
+ /* Convert the input x, y to the mu and nu angles as used by QSC.
+ * This depends on the area of the cube face. */
+ nu = atan(sqrt(xy_x * xy_x + xy_y * xy_y));
+ mu = atan2(xy_y, xy_x);
+ if (xy_x >= 0.0 && xy_x >= fabs(xy_y)) {
+ area = AREA_0;
+ } else if (xy_y >= 0.0 && xy_y >= fabs(xy_x)) {
+ area = AREA_1;
+ mu -= geometry::math::half_pi<double>();
+ } else if (xy_x < 0.0 && -xy_x >= fabs(xy_y)) {
+ area = AREA_2;
+ mu = (mu < 0.0 ? mu + geometry::math::pi<double>() : mu - geometry::math::pi<double>());
+ } else {
+ area = AREA_3;
+ mu += geometry::math::half_pi<double>();
+ }
+
+ /* Compute phi and theta for the area of definition.
+ * The inverse projection is not described in the original paper, but some
+ * good hints can be found here (as of 2011-12-14):
+ * http://fits.gsfc.nasa.gov/fitsbits/saf.93/saf.9302
+ * (search for "Message-Id: <9302181759.AA25477 at fits.cv.nrao.edu>") */
+ t = (geometry::math::pi<double>() / 12.0) * tan(mu);
+ tantheta = sin(t) / (cos(t) - (1.0 / sqrt(2.0)));
+ theta = atan(tantheta);
+ cosmu = cos(mu);
+ tannu = tan(nu);
+ cosphi = 1.0 - cosmu * cosmu * tannu * tannu * (1.0 - cos(atan(1.0 / cos(theta))));
+ if (cosphi < -1.0) {
+ cosphi = -1.0;
+ } else if (cosphi > +1.0) {
+ cosphi = +1.0;
+ }
+
+ /* Apply the result to the real area on the cube face.
+ * For the top and bottom face, we can compute phi and lam directly.
+ * For the other faces, we must use unit sphere cartesian coordinates
+ * as an intermediate step. */
+ if (this->m_proj_parm.face == FACE_TOP) {
+ phi = acos(cosphi);
+ lp_lat = geometry::math::half_pi<double>() - phi;
+ if (area == AREA_0) {
+ lp_lon = theta + geometry::math::half_pi<double>();
+ } else if (area == AREA_1) {
+ lp_lon = (theta < 0.0 ? theta + geometry::math::pi<double>() : theta - geometry::math::pi<double>());
+ } else if (area == AREA_2) {
+ lp_lon = theta - geometry::math::half_pi<double>();
+ } else /* area == AREA_3 */ {
+ lp_lon = theta;
+ }
+ } else if (this->m_proj_parm.face == FACE_BOTTOM) {
+ phi = acos(cosphi);
+ lp_lat = phi - geometry::math::half_pi<double>();
+ if (area == AREA_0) {
+ lp_lon = -theta + geometry::math::half_pi<double>();
+ } else if (area == AREA_1) {
+ lp_lon = -theta;
+ } else if (area == AREA_2) {
+ lp_lon = -theta - geometry::math::half_pi<double>();
+ } else /* area == AREA_3 */ {
+ lp_lon = (theta < 0.0 ? -theta - geometry::math::pi<double>() : -theta + geometry::math::pi<double>());
+ }
+ } else {
+ /* Compute phi and lam via cartesian unit sphere coordinates. */
+ double q, r, s, t;
+ q = cosphi;
+ t = q * q;
+ if (t >= 1.0) {
+ s = 0.0;
+ } else {
+ s = sqrt(1.0 - t) * sin(theta);
+ }
+ t += s * s;
+ if (t >= 1.0) {
+ r = 0.0;
+ } else {
+ r = sqrt(1.0 - t);
+ }
+ /* Rotate q,r,s into the correct area. */
+ if (area == AREA_1) {
+ t = r;
+ r = -s;
+ s = t;
+ } else if (area == AREA_2) {
+ r = -r;
+ s = -s;
+ } else if (area == AREA_3) {
+ t = r;
+ r = s;
+ s = -t;
+ }
+ /* Rotate q,r,s into the correct cube face. */
+ if (this->m_proj_parm.face == FACE_RIGHT) {
+ t = q;
+ q = -r;
+ r = t;
+ } else if (this->m_proj_parm.face == FACE_BACK) {
+ q = -q;
+ r = -r;
+ } else if (this->m_proj_parm.face == FACE_LEFT) {
+ t = q;
+ q = r;
+ r = -t;
+ }
+ /* Now compute phi and lam from the unit sphere coordinates. */
+ lp_lat = acos(-s) - geometry::math::half_pi<double>();
+ lp_lon = atan2(r, q);
+ if (this->m_proj_parm.face == FACE_RIGHT) {
+ lp_lon = qsc_shift_lon_origin(lp_lon, -geometry::math::half_pi<double>());
+ } else if (this->m_proj_parm.face == FACE_BACK) {
+ lp_lon = qsc_shift_lon_origin(lp_lon, -geometry::math::pi<double>());
+ } else if (this->m_proj_parm.face == FACE_LEFT) {
+ lp_lon = qsc_shift_lon_origin(lp_lon, +geometry::math::half_pi<double>());
+ }
+ }
+
+ /* Apply the shift from the sphere to the ellipsoid as described
+ * in [LK12]. */
+ if (this->m_par.es) {
+ int invert_sign;
+ double tanphi, xa;
+ invert_sign = (lp_lat < 0.0 ? 1 : 0);
+ tanphi = tan(lp_lat);
+ xa = this->m_proj_parm.b / sqrt(tanphi * tanphi + this->m_proj_parm.one_minus_f_squared);
+ lp_lat = atan(sqrt(this->m_par.a * this->m_par.a - xa * xa) / (this->m_proj_parm.one_minus_f * xa));
+ if (invert_sign) {
+ lp_lat = -lp_lat;
+ }
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "qsc_ellipsoid";
+ }
+
+ };
+
+ // Quadrilateralized Spherical Cube
+ template <typename Parameters>
+ void setup_qsc(Parameters& par, par_qsc& proj_parm)
+ {
+ /* Determine the cube face from the center of projection. */
+ if (par.phi0 >= geometry::math::half_pi<double>() - FORTPI / 2.0) {
+ proj_parm.face = FACE_TOP;
+ } else if (par.phi0 <= -(geometry::math::half_pi<double>() - FORTPI / 2.0)) {
+ proj_parm.face = FACE_BOTTOM;
+ } else if (fabs(par.lam0) <= FORTPI) {
+ proj_parm.face = FACE_FRONT;
+ } else if (fabs(par.lam0) <= geometry::math::half_pi<double>() + FORTPI) {
+ proj_parm.face = (par.lam0 > 0.0 ? FACE_RIGHT : FACE_LEFT);
+ } else {
+ proj_parm.face = FACE_BACK;
+ }
+ /* Fill in useful values for the ellipsoid <-> sphere shift
+ * described in [LK12]. */
+ if (par.es) {
+ proj_parm.a_squared = par.a * par.a;
+ proj_parm.b = par.a * sqrt(1.0 - par.es);
+ proj_parm.one_minus_f = 1.0 - (par.a - proj_parm.b) / par.a;
+ proj_parm.one_minus_f_squared = proj_parm.one_minus_f * proj_parm.one_minus_f;
+ }
+ }
+
+ }} // namespace detail::qsc
+ #endif // doxygen
+
+ /*!
+ \brief Quadrilateralized Spherical Cube 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_qsc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct qsc_ellipsoid : public detail::qsc::base_qsc_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline qsc_ellipsoid(const Parameters& par) : detail::qsc::base_qsc_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::qsc::setup_qsc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class qsc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<qsc_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void qsc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("qsc", new qsc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_QSC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/robin.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/robin.hpp
new file mode 100644
index 0000000000..bdcc5bf6b3
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/robin.hpp
@@ -0,0 +1,256 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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.
+
+ Some background on these coefficients is available at:
+
+ http://article.gmane.org/gmane.comp.gis.proj-4.devel/6039
+ http://trac.osgeo.org/proj/ticket/113
+ */
+
+ struct COEFS {
+ double c0, c1, c2, c3;
+ };
+
+ static const struct COEFS X[] = {
+ {1, 2.2199e-17, -7.15515e-05, 3.1103e-06},
+ {0.9986, -0.000482243, -2.4897e-05, -1.3309e-06},
+ {0.9954, -0.00083103, -4.48605e-05, -9.86701e-07},
+ {0.99, -0.00135364, -5.9661e-05, 3.6777e-06},
+ {0.9822, -0.00167442, -4.49547e-06, -5.72411e-06},
+ {0.973, -0.00214868, -9.03571e-05, 1.8736e-08},
+ {0.96, -0.00305085, -9.00761e-05, 1.64917e-06},
+ {0.9427, -0.00382792, -6.53386e-05, -2.6154e-06},
+ {0.9216, -0.00467746, -0.00010457, 4.81243e-06},
+ {0.8962, -0.00536223, -3.23831e-05, -5.43432e-06},
+ {0.8679, -0.00609363, -0.000113898, 3.32484e-06},
+ {0.835, -0.00698325, -6.40253e-05, 9.34959e-07},
+ {0.7986, -0.00755338, -5.00009e-05, 9.35324e-07},
+ {0.7597, -0.00798324, -3.5971e-05, -2.27626e-06},
+ {0.7186, -0.00851367, -7.01149e-05, -8.6303e-06},
+ {0.6732, -0.00986209, -0.000199569, 1.91974e-05},
+ {0.6213, -0.010418, 8.83923e-05, 6.24051e-06},
+ {0.5722, -0.00906601, 0.000182, 6.24051e-06},
+ {0.5322, -0.00677797, 0.000275608, 6.24051e-06}
+ };
+ static const struct COEFS Y[] = {
+ {-5.20417e-18, 0.0124, 1.21431e-18, -8.45284e-11},
+ {0.062, 0.0124, -1.26793e-09, 4.22642e-10},
+ {0.124, 0.0124, 5.07171e-09, -1.60604e-09},
+ {0.186, 0.0123999, -1.90189e-08, 6.00152e-09},
+ {0.248, 0.0124002, 7.10039e-08, -2.24e-08},
+ {0.31, 0.0123992, -2.64997e-07, 8.35986e-08},
+ {0.372, 0.0124029, 9.88983e-07, -3.11994e-07},
+ {0.434, 0.0123893, -3.69093e-06, -4.35621e-07},
+ {0.4958, 0.0123198, -1.02252e-05, -3.45523e-07},
+ {0.5571, 0.0121916, -1.54081e-05, -5.82288e-07},
+ {0.6176, 0.0119938, -2.41424e-05, -5.25327e-07},
+ {0.6769, 0.011713, -3.20223e-05, -5.16405e-07},
+ {0.7346, 0.0113541, -3.97684e-05, -6.09052e-07},
+ {0.7903, 0.0109107, -4.89042e-05, -1.04739e-06},
+ {0.8435, 0.0103431, -6.4615e-05, -1.40374e-09},
+ {0.8936, 0.00969686, -6.4636e-05, -8.547e-06},
+ {0.9394, 0.00840947, -0.000192841, -4.2106e-06},
+ {0.9761, 0.00616527, -0.000256, -4.2106e-06},
+ {1, 0.00328947, -0.000319159, -4.2106e-06}
+ };
+
+ // 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)); }
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 = geometry::math::r2d<double>() * (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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ 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) * geometry::math::d2r<double>();
+ if (xy_y < 0.) lp_lat = -lp_lat;
+ lp_lon /= V(X[i], t);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "robin_spheroid";
+ }
+
+ };
+
+ // Robinson
+ template <typename Parameters>
+ void setup_robin(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ROBIN_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/rouss.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/rouss.hpp
new file mode 100644
index 0000000000..542e89ada2
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/rouss.hpp
@@ -0,0 +1,223 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Copyright (c) 2003, 2006 Gerald I. Evenden
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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)));
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "rouss_ellipsoid";
+ }
+
+ };
+
+ // 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;
+
+ if (!proj_mdist_ini(par.es, proj_parm.en))
+ throw proj_exception(0);
+ 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);
+ }
+
+ }} // 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
+ - Ellipsoid
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ROUSS_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/rpoly.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/rpoly.hpp
new file mode 100644
index 0000000000..4eee0e18ce
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/rpoly.hpp
@@ -0,0 +1,168 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "rpoly_spheroid";
+ }
+
+ };
+
+ // 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.;
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_RPOLY_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/sconics.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/sconics.hpp
new file mode 100644
index 0000000000..7bdd547b4d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/sconics.hpp
@@ -0,0 +1,537 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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>
+ static 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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) ellipsoid & spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "sconics_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_sconics& 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 >= geometry::math::half_pi<double>())
+ 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.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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel
+ - lat_2: Latitude of second standard parallel
+ \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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel
+ - lat_2: Latitude of second standard parallel
+ \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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel
+ - lat_2: Latitude of second standard parallel
+ \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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel
+ - lat_2: Latitude of second standard parallel
+ \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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel
+ - lat_2: Latitude of second standard parallel
+ \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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel
+ - lat_2: Latitude of second standard parallel
+ \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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel
+ - lat_2: Latitude of second standard parallel
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_SCONICS_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/somerc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/somerc.hpp
new file mode 100644
index 0000000000..ed458e5f8a
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/somerc.hpp
@@ -0,0 +1,202 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(e_forward)
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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)) - geometry::math::half_pi<double>();
+ 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));
+ }
+
+ // INVERSE(e_inverse) ellipsoid & spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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();
+ }
+
+ static inline std::string get_name()
+ {
+ return "somerc_ellipsoid";
+ }
+
+ };
+
+ // 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);
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/stere.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/stere.hpp
new file mode 100644
index 0000000000..7d91a90fd0
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/stere.hpp
@@ -0,0 +1,502 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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;
+ };
+
+ static double
+ ssfn_(double phit, double sinphi, double eccen) {
+ sinphi *= eccen;
+ return (tan (.5 * (geometry::math::half_pi<double>() + 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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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)) - geometry::math::half_pi<double>());
+ 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;
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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 * (geometry::math::half_pi<double>() + phi_l));
+ xy_x *= sinphi;
+ xy_y = rho * this->m_proj_parm.cosX1 * cosphi - xy_y * this->m_proj_parm.sinX1* sinphi;
+ halfpi = geometry::math::half_pi<double>();
+ halfe = .5 * this->m_par.e;
+ break;
+ case N_POLE:
+ xy_y = -xy_y;
+ case S_POLE:
+ phi_l = geometry::math::half_pi<double>() - 2. * atan(tp = - rho / this->m_proj_parm.akm1);
+ halfpi = -geometry::math::half_pi<double>();
+ 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();;
+ }
+
+ static inline std::string get_name()
+ {
+ return "stere_ellipsoid";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 - geometry::math::half_pi<double>()) < TOL) throw proj_exception();;
+ xy_x = sinlam * ( xy_y = this->m_proj_parm.akm1 * tan(FORTPI + .5 * lp_lat) );
+ xy_y *= coslam;
+ break;
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "stere_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_stere& proj_parm) /* general initialization */
+ {
+ double t;
+
+ if (fabs((t = fabs(par.phi0)) - geometry::math::half_pi<double>()) < 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 - geometry::math::half_pi<double>()) < 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)) - geometry::math::half_pi<double>();
+ 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;
+ }
+ } 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 - geometry::math::half_pi<double>()) >= EPS10 ?
+ cos(proj_parm.phits) / tan(FORTPI - .5 * proj_parm.phits) :
+ 2. * par.k0 ;
+ break;
+ }
+ }
+ }
+
+
+ // 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 : geometry::math::half_pi<double>();
+ 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 ? - geometry::math::half_pi<double>(): geometry::math::half_pi<double>();
+ if (!par.es) throw proj_exception(-34);
+ par.k0 = .994;
+ par.x0 = 2000000.;
+ par.y0 = 2000000.;
+ proj_parm.phits = geometry::math::half_pi<double>();
+ 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
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \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 Stereographic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \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);
+ }
+ };
+
+ /*!
+ \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
+ \par Projection parameters
+ - south: Denotes southern hemisphere UTM zone (boolean)
+ \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 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
+ \par Projection parameters
+ - south: Denotes southern hemisphere UTM zone (boolean)
+ \par Example
+ \image html ex_ups.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct ups_spheroid : public detail::stere::base_stere_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline ups_spheroid(const Parameters& par) : detail::stere::base_stere_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::stere::setup_ups(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
+ {
+ if (par.es)
+ return new base_v_fi<ups_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<ups_spheroid<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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_STERE_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/sterea.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/sterea.hpp
new file mode 100644
index 0000000000..81b3d3d436
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/sterea.hpp
@@ -0,0 +1,393 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Copyright (c) 2003 Gerald I. Evenden
+
+// 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 projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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_);
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "sterea_ellipsoid";
+ }
+
+ };
+
+ // 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;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/sts.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/sts.hpp
new file mode 100644
index 0000000000..f8ec9164b3
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/sts.hpp
@@ -0,0 +1,301 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "sts_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_sts& proj_parm, double p, double q, int mode)
+ {
+ par.es = 0.;
+ 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_STS_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/tcc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/tcc.hpp
new file mode 100644
index 0000000000..b491be9a43
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/tcc.hpp
@@ -0,0 +1,151 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "tcc_spheroid";
+ }
+
+ };
+
+ // Transverse Central Cylindrical
+ template <typename Parameters>
+ void setup_tcc(Parameters& par, par_tcc& proj_parm)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_TCC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/tcea.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/tcea.hpp
new file mode 100644
index 0000000000..14f2ad3eac
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/tcea.hpp
@@ -0,0 +1,158 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "tcea_spheroid";
+ }
+
+ };
+
+ // Transverse Cylindrical Equal Area
+ template <typename Parameters>
+ void setup_tcea(Parameters& par, par_tcea& proj_parm)
+ {
+ proj_parm.rk0 = 1 / par.k0;
+ 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_TCEA_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/tmerc.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/tmerc.hpp
new file mode 100644
index 0000000000..b27c19d5c2
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/tmerc.hpp
@@ -0,0 +1,504 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(e_forward) ellipse
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 < -geometry::math::half_pi<double>() || lp_lon > geometry::math::half_pi<double>() )
+ {
+ 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.) )
+ ))));
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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) >= geometry::math::half_pi<double>()) {
+ lp_lat = xy_y < 0. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ 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;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "tmerc_ellipsoid";
+ }
+
+ };
+
+ // 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) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 < -geometry::math::half_pi<double>() || lp_lon > geometry::math::half_pi<double>() )
+ {
+ 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);
+ }
+
+ // INVERSE(s_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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.;
+ }
+
+ static inline std::string get_name()
+ {
+ return "tmerc_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_tmerc& proj_parm) /* general initialization */
+ {
+ if (par.es) {
+ if (!pj_enfn(par.es, proj_parm.en))
+ throw proj_exception(0);
+ proj_parm.ml0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en);
+ proj_parm.esp = par.es / (1. - par.es);
+ } else {
+ proj_parm.esp = par.k0;
+ proj_parm.ml0 = .5 * proj_parm.esp;
+ }
+ }
+
+
+ // 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;
+
+ 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) + geometry::math::pi<double>()) * 30. / geometry::math::pi<double>())) < 0)
+ zone = 0;
+ else if (zone >= 60)
+ zone = 59;
+ par.lam0 = (zone + .5) * geometry::math::pi<double>() / 30. - geometry::math::pi<double>();
+ 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 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);
+ }
+ };
+
+ /*!
+ \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
+ \par Projection parameters
+ - zone: UTM Zone (integer)
+ - south: Denotes southern hemisphere UTM zone (boolean)
+ \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 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
+ \par Projection parameters
+ - zone: UTM Zone (integer)
+ - south: Denotes southern hemisphere UTM zone (boolean)
+ \par Example
+ \image html ex_utm.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct utm_spheroid : public detail::tmerc::base_tmerc_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline utm_spheroid(const Parameters& par) : detail::tmerc::base_tmerc_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::tmerc::setup_utm(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
+ {
+ if (par.es)
+ return new base_v_fi<utm_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<utm_spheroid<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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_TMERC_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/tpeqd.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/tpeqd.hpp
new file mode 100644
index 0000000000..3200c0ba11
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/tpeqd.hpp
@@ -0,0 +1,216 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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/aasincos.hpp>
+
+namespace boost { namespace geometry { namespace projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "tpeqd_spheroid";
+ }
+
+ };
+
+ // 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 = geometry::math::half_pi<double>() - 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.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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ - lon_1 (degrees)
+ - lat_2: Latitude of second standard parallel (degrees)
+ - lon_2 (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/urm5.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/urm5.hpp
new file mode 100644
index 0000000000..f336137266
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/urm5.hpp
@@ -0,0 +1,162 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "urm5_spheroid";
+ }
+
+ };
+
+ // 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.;
+ }
+
+ }} // 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
+ - no inverse
+ \par Projection parameters
+ - n (real)
+ - q (real)
+ - alpha: Alpha (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_URM5_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/urmfps.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/urmfps.hpp
new file mode 100644
index 0000000000..5a1e158387
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/urmfps.hpp
@@ -0,0 +1,214 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "urmfps_spheroid";
+ }
+
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_urmfps& proj_parm)
+ {
+ proj_parm.C_y = Cy / proj_parm.n;
+ par.es = 0.;
+ }
+
+
+ // 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
+ \par Projection parameters
+ - n (real)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/vandg.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/vandg.hpp
new file mode 100644
index 0000000000..78a4e6f187
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/vandg.hpp
@@ -0,0 +1,212 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 / geometry::math::half_pi<double>());
+ 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 = geometry::math::pi<double>() * tan(.5 * asin(p2));
+ if (lp_lat < 0.) xy_y = -xy_y;
+ } else {
+ al = .5 * fabs(geometry::math::pi<double>() / lp_lon - lp_lon / geometry::math::pi<double>());
+ 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 = geometry::math::pi<double>() * (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 / geometry::math::pi<double>());
+ 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. ? -geometry::math::pi<double>() : geometry::math::pi<double>());
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ 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 = - geometry::math::pi<double>() * ay * (r + PISQ);
+ c3 = r2 + geometry::math::two_pi<double>() * (ay * r + geometry::math::pi<double>() * (y2 + geometry::math::pi<double>() * (ay + geometry::math::half_pi<double>())));
+ c2 = c1 + PISQ * (r - 3. * y2);
+ c0 = geometry::math::pi<double>() * 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. : geometry::math::pi<double>()) : acos(d);
+ lp_lat = geometry::math::pi<double>() * (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();;
+ }
+
+ static inline std::string get_name()
+ {
+ return "vandg_spheroid";
+ }
+
+ };
+
+ // van der Grinten (I)
+ template <typename Parameters>
+ void setup_vandg(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_VANDG_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/vandg2.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/vandg2.hpp
new file mode 100644
index 0000000000..b4ff3140b8
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/vandg2.hpp
@@ -0,0 +1,214 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 = geometry::math::pi<double>() * (lp_lat < 0. ? -bt : bt) / (1. + ct);
+ } else {
+ at = 0.5 * fabs(geometry::math::pi<double>() / lp_lon - lp_lon / geometry::math::pi<double>());
+ if (this->m_proj_parm.vdg3) {
+ x1 = bt / (1. + ct);
+ xy_x = geometry::math::pi<double>() * (sqrt(at * at + 1. - x1 * x1) - at);
+ xy_y = geometry::math::pi<double>() * x1;
+ } else {
+ x1 = (ct * sqrt(1. + at * at) - at * ct * ct) /
+ (1. + at * at * bt * bt);
+ xy_x = geometry::math::pi<double>() * x1;
+ xy_y = geometry::math::pi<double>() * sqrt(1. - x1 * (x1 + 2. * at) + TOL);
+ }
+ if ( lp_lon < 0.) xy_x = -xy_x;
+ if ( lp_lat < 0.) xy_y = -xy_y;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "vandg2_spheroid";
+ }
+
+ };
+
+ // van der Grinten II
+ template <typename Parameters>
+ void setup_vandg2(Parameters& par, par_vandg2& proj_parm)
+ {
+ proj_parm.vdg3 = 0;
+ }
+
+ // van der Grinten III
+ template <typename Parameters>
+ void setup_vandg3(Parameters& par, par_vandg2& proj_parm)
+ {
+ proj_parm.vdg3 = 1;
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_VANDG2_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/vandg4.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/vandg4.hpp
new file mode 100644
index 0000000000..2b0daebb4c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/vandg4.hpp
@@ -0,0 +1,173 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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) - geometry::math::half_pi<double>()) < 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) - geometry::math::half_pi<double>()) < 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 = geometry::math::half_pi<double>() * x1;
+ xy_y = geometry::math::half_pi<double>() * sqrt(1. + dt * fabs(x1) - x1 * x1);
+ if (lp_lon < 0.) xy_x = -xy_x;
+ if (lp_lat < 0.) xy_y = -xy_y;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "vandg4_spheroid";
+ }
+
+ };
+
+ // van der Grinten IV
+ template <typename Parameters>
+ void setup_vandg4(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_VANDG4_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/wag2.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/wag2.hpp
new file mode 100644
index 0000000000..491fbcda2a
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/wag2.hpp
@@ -0,0 +1,154 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "wag2_spheroid";
+ }
+
+ };
+
+ // Wagner II
+ template <typename Parameters>
+ void setup_wag2(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_WAG2_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/wag3.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/wag3.hpp
new file mode 100644
index 0000000000..69ff36fac3
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/wag3.hpp
@@ -0,0 +1,160 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "wag3_spheroid";
+ }
+
+ };
+
+ // 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.;
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_WAG3_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/wag7.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/wag7.hpp
new file mode 100644
index 0000000000..b20ac4c51e
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/wag7.hpp
@@ -0,0 +1,143 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ static inline std::string get_name()
+ {
+ return "wag7_spheroid";
+ }
+
+ };
+
+ // Wagner VII
+ template <typename Parameters>
+ void setup_wag7(Parameters& par)
+ {
+ 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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_WAG7_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/wink1.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/wink1.hpp
new file mode 100644
index 0000000000..96c35a32b9
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/wink1.hpp
@@ -0,0 +1,155 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, 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));
+ }
+
+ static inline std::string get_name()
+ {
+ return "wink1_spheroid";
+ }
+
+ };
+
+ // 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.;
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_WINK1_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/proj/wink2.hpp b/3party/boost/boost/geometry/extensions/gis/projections/proj/wink2.hpp
new file mode 100644
index 0000000000..0251af1424
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/proj/wink2.hpp
@@ -0,0 +1,170 @@
+#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-2015 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
+
+// Last updated version of proj: 4.9.1
+
+// 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/geometry/util/math.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 projections
+{
+ #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) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ 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 = geometry::math::pi<double>() * 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.) ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ 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);
+ }
+
+ static inline std::string get_name()
+ {
+ return "wink2_spheroid";
+ }
+
+ };
+
+ // 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.;
+ }
+
+ }} // 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
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ \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::projections
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_WINK2_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/project_inverse_transformer.hpp b/3party/boost/boost/geometry/extensions/gis/projections/project_inverse_transformer.hpp
new file mode 100644
index 0000000000..136d51133b
--- /dev/null
+++ b/3party/boost/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 projections
+{
+
+
+/*!
+ \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::conversion::point_to_point<Cartesian, LatLong, 2,
+ geometry::dimension<Cartesian>::value> ::apply(p1, p2);
+ return m_prj->inverse(p1, p2);
+ }
+
+};
+
+}}} // namespace boost::geometry::projections
+
+
+#endif // BOOST_GEOMETRY_STRATEGY_PROJECT_INVERSE_TRANSFORMER_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/project_transformer.hpp b/3party/boost/boost/geometry/extensions/gis/projections/project_transformer.hpp
new file mode 100644
index 0000000000..50877a2ac1
--- /dev/null
+++ b/3party/boost/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/detail/convert_point_to_point.hpp>
+#include <boost/geometry/extensions/gis/projections/factory.hpp>
+#include <boost/geometry/extensions/gis/projections/parameters.hpp>
+
+
+
+namespace boost { namespace geometry { namespace projections
+{
+/*!
+ \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::conversion::point_to_point<LatLong, Cartesian, 2,
+ geometry::dimension<Cartesian>::value> ::apply(p1, p2);
+ return m_prj->forward(p1, p2);
+ }
+
+};
+
+}}} // namespace boost::geometry::projections
+
+
+#endif // BOOST_GEOMETRY_STRATEGY_PROJECT_TRANSFORMER_HPP
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/projection.hpp b/3party/boost/boost/geometry/extensions/gis/projections/projection.hpp
new file mode 100644
index 0000000000..f84e140a7f
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/projection.hpp
@@ -0,0 +1,72 @@
+// 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 projections
+{
+
+/*!
+ \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 :
+
+ typedef LL geographic_point_type; ///< latlong point type
+ typedef XY cartesian_point_type; ///< xy point type
+
+ /// 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 const& params() const = 0;
+
+ /// Returns mutable parameters of projection
+ virtual parameters& mutable_params() = 0;
+
+ virtual ~projection() {}
+
+};
+
+}}} // namespace boost::geometry::projections
+
+
+
+#endif
+
diff --git a/3party/boost/boost/geometry/extensions/gis/projections/projection_point_type.hpp b/3party/boost/boost/geometry/extensions/gis/projections/projection_point_type.hpp
new file mode 100644
index 0000000000..635b6f8879
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/gis/projections/projection_point_type.hpp
@@ -0,0 +1,44 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2012 Krzysztof Czainski
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// 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)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PROJECTION_POINT_TYPE_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PROJECTION_POINT_TYPE_HPP
+
+namespace boost { namespace geometry { namespace projections
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Projection, typename CoordinateSystemTag>
+struct projection_point_type
+{};
+
+template <typename Projection>
+struct projection_point_type<Projection, cartesian_tag>
+{
+ typedef typename Projection::cartesian_point_type type;
+};
+
+template <typename Projection>
+struct projection_point_type<Projection, geographic_tag>
+{
+ typedef typename Projection::geographic_point_type type;
+};
+
+} // detail
+#endif // DOXYGEN_NO_DETAIL
+
+}}} // boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PROJECTION_POINT_TYPE_HPP
diff --git a/3party/boost/boost/geometry/extensions/index/rtree/helpers.hpp b/3party/boost/boost/geometry/extensions/index/rtree/helpers.hpp
new file mode 100644
index 0000000000..45a71f31d7
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/index/rtree/rtree.hpp b/3party/boost/boost/geometry/extensions/index/rtree/rtree.hpp
new file mode 100644
index 0000000000..a9e9ac6c82
--- /dev/null
+++ b/3party/boost/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 BOOST_GEOMETRY_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 BOOST_GEOMETRY_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/3party/boost/boost/geometry/extensions/index/rtree/rtree_leaf.hpp b/3party/boost/boost/geometry/extensions/index/rtree/rtree_leaf.hpp
new file mode 100644
index 0000000000..95d1a86b13
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/index/rtree/rtree_node.hpp b/3party/boost/boost/geometry/extensions/index/rtree/rtree_node.hpp
new file mode 100644
index 0000000000..de35ef270b
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/iterators/circular_iterator.hpp b/3party/boost/boost/geometry/extensions/iterators/circular_iterator.hpp
new file mode 100644
index 0000000000..31ae5ce1b7
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/iterators/section_iterators.hpp b/3party/boost/boost/geometry/extensions/iterators/section_iterators.hpp
new file mode 100644
index 0000000000..d0751f6d29
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/iterators/segment_returning_iterator.hpp b/3party/boost/boost/geometry/extensions/iterators/segment_returning_iterator.hpp
new file mode 100644
index 0000000000..d203045374
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/iterators/segment_returning_iterator.hpp
@@ -0,0 +1,140 @@
+// 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/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <boost/geometry/core/assert.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_GEOMETRY_ASSERT(m_prev != m_end);
+ ++m_it;
+ }
+ }
+
+ reference operator*()
+ {
+ BOOST_GEOMETRY_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/3party/boost/boost/geometry/extensions/multi/algorithms/dissolve.hpp b/3party/boost/boost/geometry/extensions/multi/algorithms/dissolve.hpp
new file mode 100644
index 0000000000..dbfec1f1d7
--- /dev/null
+++ b/3party/boost/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/core/point_type.hpp>
+#include <boost/geometry/core/tags.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 RescalePolicy, typename OutputIterator>
+ static inline OutputIterator apply(Multi const& multi, RescalePolicy const& rescale_policy, 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, rescale_policy, 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, rescale_policy, 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/3party/boost/boost/geometry/extensions/nsphere/algorithms/append.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/append.hpp
new file mode 100644
index 0000000000..3a271b2ec2
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/nsphere/algorithms/area.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/area.hpp
new file mode 100644
index 0000000000..1ca96a37b1
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/algorithms/area.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_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/radius.hpp>
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace area
+{
+
+template<typename C>
+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;
+
+ template <typename S>
+ 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>
+struct area<Geometry, nsphere_tag>
+ : detail::area::circle_area<Geometry>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_AREA_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/algorithms/assign.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/assign.hpp
new file mode 100644
index 0000000000..0d83fa691b
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/nsphere/algorithms/centroid.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/centroid.hpp
new file mode 100644
index 0000000000..908f6480ed
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/algorithms/centroid.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_CENTROID_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_CENTROID_HPP
+
+#include <boost/geometry/algorithms/centroid.hpp>
+
+#include <boost/geometry/extensions/nsphere/views/center_view.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace centroid
+{
+
+struct centroid_nsphere
+{
+ template<typename NSphere, typename PointCentroid, typename Strategy>
+ static inline void apply(NSphere const& nsphere, PointCentroid& centroid,
+ Strategy const&)
+ {
+ geometry::convert(center_view<const NSphere>(nsphere), centroid);
+ }
+};
+
+}} // namespace detail::centroid
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Geometry>
+struct centroid<Geometry, nsphere_tag>
+ : detail::centroid::centroid_nsphere
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_CENTROID_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/algorithms/clear.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/clear.hpp
new file mode 100644
index 0000000000..c59f7e838c
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/nsphere/algorithms/covered_by.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/covered_by.hpp
new file mode 100644
index 0000000000..d4f3884edb
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/algorithms/covered_by.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_COVERED_BY_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_COVERED_BY_HPP
+
+
+#include <boost/geometry/algorithms/covered_by.hpp>
+
+#include <boost/geometry/extensions/nsphere/strategies/cartesian/nsphere_in_box.hpp>
+#include <boost/geometry/extensions/nsphere/strategies/cartesian/point_in_nsphere.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename NSphere, typename Box>
+struct covered_by<NSphere, Box, nsphere_tag, box_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(NSphere const& nsphere, Box const& box, Strategy const& strategy)
+ {
+ assert_dimension_equal<NSphere, Box>();
+ boost::ignore_unused_variable_warning(strategy);
+ return strategy.apply(nsphere, box);
+ }
+};
+
+template <typename Point, typename NSphere>
+struct covered_by<Point, NSphere, point_tag, nsphere_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Point const& point, NSphere const& nsphere, Strategy const& strategy)
+ {
+ assert_dimension_equal<Point, NSphere>();
+ boost::ignore_unused_variable_warning(strategy);
+ return strategy.apply(point, nsphere);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_COVERED_BY_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/algorithms/disjoint.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/disjoint.hpp
new file mode 100644
index 0000000000..9623e7d7e1
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/algorithms/disjoint.hpp
@@ -0,0 +1,147 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_DISJOINT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_DISJOINT_HPP
+
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/algorithms/comparable_distance.hpp>
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/extensions/nsphere/views/center_view.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace disjoint
+{
+
+// Arvo's algorithm implemented
+// TODO - implement the method mentioned in the article below and compare performance
+// "On Faster Sphere-Box Overlap Testing" - Larsson, T.; Akeine-Moller, T.; Lengyel, E.
+template
+<
+ typename Box, typename NSphere,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct box_nsphere_comparable_distance_cartesian
+{
+ typedef typename geometry::select_most_precise<
+ typename coordinate_type<typename point_type<Box>::type>::type,
+ typename coordinate_type<typename point_type<NSphere>::type>::type
+ >::type coordinate_type;
+
+ typedef typename geometry::default_distance_result<
+ Box,
+ typename point_type<NSphere>::type
+ >::type result_type;
+
+ static inline result_type apply(Box const& box, NSphere const& nsphere)
+ {
+ result_type r = 0;
+
+ if( get<Dimension>(nsphere) < get<min_corner, Dimension>(box) )
+ {
+ coordinate_type tmp = get<min_corner, Dimension>(box) - get<Dimension>(nsphere);
+ r = tmp*tmp;
+ }
+ else if( get<max_corner, Dimension>(box) < get<Dimension>(nsphere) )
+ {
+ coordinate_type tmp = get<Dimension>(nsphere) - get<max_corner, Dimension>(box);
+ r = tmp*tmp;
+ }
+
+ return r + box_nsphere_comparable_distance_cartesian<
+ Box, NSphere, Dimension + 1, DimensionCount
+ >::apply(box, nsphere);
+ }
+};
+
+template <typename Box, typename NSphere, std::size_t DimensionCount>
+struct box_nsphere_comparable_distance_cartesian<Box, NSphere, DimensionCount, DimensionCount>
+{
+ static inline int apply(Box const& , NSphere const& )
+ {
+ return 0;
+ }
+};
+
+}} // namespace detail::disjoint
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Point, typename NSphere, std::size_t DimensionCount, bool Reverse>
+struct disjoint<Point, NSphere, DimensionCount, point_tag, nsphere_tag, Reverse>
+{
+ static inline bool apply(Point const& p, NSphere const& s)
+ {
+ typedef typename coordinate_system<Point>::type p_cs;
+ typedef typename coordinate_system<NSphere>::type s_cs;
+ static const bool check_cs = ::boost::is_same<p_cs, cs::cartesian>::value && ::boost::is_same<s_cs, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(check_cs, NOT_IMPLEMENTED_FOR_THOSE_COORDINATE_SYSTEMS, (p_cs, s_cs));
+
+ return get_radius<0>(s) * get_radius<0>(s)
+ < geometry::comparable_distance(p, center_view<const NSphere>(s));
+ }
+};
+
+template <typename NSphere, typename Box, std::size_t DimensionCount, bool Reverse>
+struct disjoint<NSphere, Box, DimensionCount, nsphere_tag, box_tag, Reverse>
+{
+ static inline bool apply(NSphere const& s, Box const& b)
+ {
+ typedef typename coordinate_system<Box>::type b_cs;
+ typedef typename coordinate_system<NSphere>::type s_cs;
+ static const bool check_cs = ::boost::is_same<b_cs, cs::cartesian>::value && ::boost::is_same<s_cs, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(check_cs, NOT_IMPLEMENTED_FOR_THOSE_COORDINATE_SYSTEMS, (b_cs, s_cs));
+
+ return get_radius<0>(s) * get_radius<0>(s)
+ < geometry::detail::disjoint::box_nsphere_comparable_distance_cartesian<
+ Box, NSphere, 0, DimensionCount
+ >::apply(b, s);
+ }
+};
+
+template <typename NSphere1, typename NSphere2, std::size_t DimensionCount, bool Reverse>
+struct disjoint<NSphere1, NSphere2, DimensionCount, nsphere_tag, nsphere_tag, Reverse>
+{
+ static inline bool apply(NSphere1 const& s1, NSphere2 const& s2)
+ {
+ typedef typename coordinate_system<NSphere1>::type s1_cs;
+ typedef typename coordinate_system<NSphere2>::type s2_cs;
+ static const bool check_cs = ::boost::is_same<s1_cs, cs::cartesian>::value && ::boost::is_same<s2_cs, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(check_cs, NOT_IMPLEMENTED_FOR_THOSE_COORDINATE_SYSTEMS, (s1_cs, s2_cs));
+
+ /*return get_radius<0>(s1) + get_radius<0>(s2)
+ < ::sqrt(geometry::comparable_distance(center_view<NSphere>(s1), center_view<NSphere>(s2)));*/
+
+ return get_radius<0>(s1) * get_radius<0>(s1) + 2 * get_radius<0>(s1) * get_radius<0>(s2) + get_radius<0>(s2) * get_radius<0>(s2)
+ < geometry::comparable_distance(center_view<const NSphere1>(s1), center_view<const NSphere2>(s2));
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_DISJOINT_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/algorithms/envelope.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/envelope.hpp
new file mode 100644
index 0000000000..82164003c6
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/algorithms/envelope.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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/radius.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)
+struct envelope_nsphere
+{
+ template <typename Nsphere, typename Box>
+ static inline void apply(Nsphere const& nsphere, Box& mbr)
+ {
+ 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>
+struct envelope<Nsphere, nsphere_tag>
+ : detail::envelope::envelope_nsphere
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_ENVELOPE_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/algorithms/equals.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/equals.hpp
new file mode 100644
index 0000000000..11b94bbb19
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/algorithms/equals.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) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_EQUALS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_EQUALS_HPP
+
+
+#include <boost/geometry/algorithms/equals.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace equals
+{
+
+
+template
+<
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct nsphere_nsphere
+{
+ template <typename S1, typename S2>
+ static inline bool apply(S1 const& s1, S2 const& s2)
+ {
+ if ( !geometry::math::equals(get<Dimension>(s1), get<Dimension>(s2)) )
+ {
+ return false;
+ }
+ return nsphere_nsphere<Dimension + 1, DimensionCount>::apply(s1, s2);
+ }
+};
+
+template <std::size_t DimensionCount>
+struct nsphere_nsphere<DimensionCount, DimensionCount>
+{
+ template <typename S1, typename S2>
+ static inline bool apply(S1 const& , S2 const& )
+ {
+ return true;
+ }
+};
+
+
+}} // namespace detail::equals
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename NSphere1, typename NSphere2, std::size_t DimensionCount, bool Reverse>
+struct equals<NSphere1, NSphere2, nsphere_tag, nsphere_tag, DimensionCount, Reverse>
+{
+ template <typename S1, typename S2>
+ static inline bool apply(S1 const& s1, S2 const& s2)
+ {
+ return detail::equals::nsphere_nsphere<0, DimensionCount>::apply(s1, s2)
+ && geometry::math::equals(get_radius<0>(s1), get_radius<0>(s2));
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_EQUALS_HPP
+
diff --git a/3party/boost/boost/geometry/extensions/nsphere/algorithms/expand.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/expand.hpp
new file mode 100644
index 0000000000..a87d5cf03b
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/algorithms/expand.hpp
@@ -0,0 +1,133 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_EXPAND_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_EXPAND_HPP
+
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.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 StrategyLess, typename StrategyGreater,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct nsphere_loop
+{
+ template <typename Box, typename NSphere>
+ static inline void apply(Box& box, NSphere const& source)
+ {
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyLess, 1, NSphere, Dimension
+ >::type less_type;
+
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyGreater, -1, NSphere, Dimension
+ >::type greater_type;
+
+ typedef typename select_coordinate_type<NSphere, Box>::type coordinate_type;
+
+ less_type less;
+ greater_type greater;
+
+ coordinate_type const min_coord = get<Dimension>(source) - get_radius<0>(source);
+ coordinate_type const max_coord = get<Dimension>(source) + get_radius<0>(source);
+
+ if (less(min_coord, get<min_corner, Dimension>(box)))
+ {
+ set<min_corner, Dimension>(box, min_coord);
+ }
+
+ if (greater(max_coord, get<max_corner, Dimension>(box)))
+ {
+ set<max_corner, Dimension>(box, max_coord);
+ }
+
+ nsphere_loop
+ <
+ StrategyLess, StrategyGreater,
+ Dimension + 1, DimensionCount
+ >::apply(box, source);
+ }
+};
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t DimensionCount
+>
+struct nsphere_loop
+ <
+ StrategyLess, StrategyGreater,
+ DimensionCount, DimensionCount
+ >
+{
+ template <typename Box, typename NSphere>
+ static inline void apply(Box&, NSphere const&) {}
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// Box + Nsphere -> new box containing also nsphere
+template
+<
+ typename BoxOut, typename NSphere,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand<BoxOut, NSphere, StrategyLess, StrategyGreater, box_tag, nsphere_tag>
+ : detail::expand::nsphere_loop
+ <
+ StrategyLess, StrategyGreater,
+ 0, dimension<NSphere>::type::value
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_EXPAND_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/algorithms/num_points.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/num_points.hpp
new file mode 100644
index 0000000000..e89714bb6c
--- /dev/null
+++ b/3party/boost/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, bool AddForOpen>
+struct num_points<Geometry, AddForOpen, nsphere_tag>
+ : detail::counting::other_count<1>
+{};
+
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_NUM_POINTS_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/algorithms/within.hpp b/3party/boost/boost/geometry/extensions/nsphere/algorithms/within.hpp
new file mode 100644
index 0000000000..72119ec43b
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/algorithms/within.hpp
@@ -0,0 +1,232 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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/core/tags.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/access.hpp>
+#include <boost/geometry/extensions/nsphere/core/radius.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, point_tag, P, point_type
+ >::type strategy_type;
+ typedef typename services::return_type<strategy_type, P, point_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, P, point_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>
+struct within<P, Circle, point_tag, nsphere_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(P const& p, Circle const& c, Strategy const& strategy)
+ {
+ ::boost::ignore_unused_variable_warning(strategy);
+ return strategy.apply(p, c);
+ //return detail::within::point_in_circle(p, c);
+ }
+};
+
+template <typename Box, typename Circle>
+struct within<Box, Circle, box_tag, nsphere_tag>
+{
+ template <typename 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>
+struct within<Linestring, Circle, linestring_tag, nsphere_tag>
+{
+ template <typename 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>
+struct within<Ring, Circle, ring_tag, nsphere_tag>
+{
+ template <typename 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>
+struct within<Polygon, Circle, polygon_tag, nsphere_tag>
+{
+ template <typename 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>
+struct within<M, C, multi_polygon_tag, nsphere_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(M const& m, C const& c, Strategy const&)
+ {
+ return detail::within::multi_polygon_in_circle(m, c);
+ }
+};
+
+
+
+template <typename NSphere, typename Box>
+struct within<NSphere, Box, nsphere_tag, box_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(NSphere const& nsphere, Box const& box, Strategy const& strategy)
+ {
+ assert_dimension_equal<NSphere, Box>();
+ boost::ignore_unused_variable_warning(strategy);
+ return strategy.apply(nsphere, box);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_WITHIN_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/core/access.hpp b/3party/boost/boost/geometry/extensions/nsphere/core/access.hpp
new file mode 100644
index 0000000000..500a92660a
--- /dev/null
+++ b/3party/boost/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, boost::false_type>
+{
+ 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/3party/boost/boost/geometry/extensions/nsphere/core/geometry_id.hpp b/3party/boost/boost/geometry/extensions/nsphere/core/geometry_id.hpp
new file mode 100644
index 0000000000..ccf5cf84a7
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/nsphere/core/radius.hpp b/3party/boost/boost/geometry/extensions/nsphere/core/radius.hpp
new file mode 100644
index 0000000000..331b7243a4
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/core/radius.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.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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/geometry/core/radius.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename S>
+struct radius_type<nsphere_tag, S>
+{
+ typedef typename traits::radius_type<S>::type type;
+};
+
+template <typename S, std::size_t D>
+struct radius_access<nsphere_tag, S, D, boost::false_type>
+ : detail::radius_access<nsphere_tag, S, D>
+{
+ BOOST_STATIC_ASSERT((D == 0));
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_RADIUS_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/core/replace_point_type.hpp b/3party/boost/boost/geometry/extensions/nsphere/core/replace_point_type.hpp
new file mode 100644
index 0000000000..7d250bb184
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/core/replace_point_type.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_REPLACE_POINT_TYPE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_REPLACE_POINT_TYPE_HPP
+
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+#include <boost/geometry/extensions/nsphere/geometries/nsphere.hpp>
+#include <boost/geometry/extensions/util/replace_point_type.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/3party/boost/boost/geometry/extensions/nsphere/core/tags.hpp b/3party/boost/boost/geometry/extensions/nsphere/core/tags.hpp
new file mode 100644
index 0000000000..b89b072021
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/core/tags.hpp
@@ -0,0 +1,32 @@
+// 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
+{
+
+// TEMP: areal_tag commented out to prevent falling into the implementation for Areal geometries
+// in the new implementation of disjoint().
+// Besides this tag is invalid in the case of Dimension != 2
+
+/// Convenience 2D (circle) or 3D (sphere) n-sphere identifying tag
+struct nsphere_tag : single_tag/*, areal_tag*/ {};
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_TAGS_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/core/topological_dimension.hpp b/3party/boost/boost/geometry/extensions/nsphere/core/topological_dimension.hpp
new file mode 100644
index 0000000000..f0e7c9cd59
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/nsphere/geometries/concepts/check.hpp b/3party/boost/boost/geometry/extensions/nsphere/geometries/concepts/check.hpp
new file mode 100644
index 0000000000..c8d2fb7c47
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/geometries/concepts/check.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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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
+{
+
+template <typename Geometry>
+struct check<Geometry, nsphere_tag, true>
+ : detail::concept_check::check<concept::ConstNsphere<Geometry> >
+{};
+
+template <typename Geometry>
+struct check<Geometry, nsphere_tag, false>
+ : detail::concept_check::check<concept::Nsphere<Geometry> >
+{};
+
+} // namespace dispatch
+#endif
+
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_CHECK_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp b/3party/boost/boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp
new file mode 100644
index 0000000000..03decb40d3
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/nsphere/geometries/nsphere.hpp b/3party/boost/boost/geometry/extensions/nsphere/geometries/nsphere.hpp
new file mode 100644
index 0000000000..4f7cb72b31
--- /dev/null
+++ b/3party/boost/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)
+ {
+ 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>, 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/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/bounds.hpp b/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/bounds.hpp
new file mode 100644
index 0000000000..919d835798
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/bounds.hpp
@@ -0,0 +1,46 @@
+// Boost.Geometry Index
+//
+// n-dimensional bounds
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
+
+#include <boost/geometry/index/detail/algorithms/bounds.hpp>
+
+namespace boost { namespace geometry { namespace index { namespace detail {
+
+template <typename Geometry, typename Bounds, std::size_t DimensionIndex, std::size_t DimensionCount>
+struct bounds_nsphere_box
+{
+ static inline void apply(Geometry const& g, Bounds & b)
+ {
+ set<min_corner, DimensionIndex>(b, get<DimensionIndex>(g) - get_radius<0>(g));
+ set<max_corner, DimensionIndex>(b, get<DimensionIndex>(g) + get_radius<0>(g));
+ bounds_nsphere_box<Geometry, Bounds, DimensionIndex+1, DimensionCount>::apply(g, b);
+ }
+};
+
+template <typename Geometry, typename Bounds, std::size_t DimensionCount>
+struct bounds_nsphere_box<Geometry, Bounds, DimensionCount, DimensionCount>
+{
+ static inline void apply(Geometry const& , Bounds & ) {}
+};
+
+namespace dispatch {
+
+template <typename Geometry, typename Bounds>
+struct bounds<Geometry, Bounds, nsphere_tag, box_tag>
+ : bounds_nsphere_box<Geometry, Bounds, 0, dimension<Geometry>::value>
+{};
+
+} // namespace dispatch
+
+}}}} // namespace boost::geometry::index::detail
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/comparable_distance_near.hpp b/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/comparable_distance_near.hpp
new file mode 100644
index 0000000000..96cf239730
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/comparable_distance_near.hpp
@@ -0,0 +1,42 @@
+// Boost.Geometry Index
+//
+// squared distance between point and nearest point of the box or point
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_NEAR_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_NEAR_HPP
+
+#include <boost/geometry/index/detail/algorithms/comparable_distance_near.hpp>
+
+#include <boost/geometry/extensions/nsphere/views/center_view.hpp>
+#include <boost/geometry/util/math.hpp>
+
+namespace boost { namespace geometry { namespace index { namespace detail {
+
+template <
+ typename Point,
+ typename Indexable,
+ size_t N>
+struct sum_for_indexable<Point, Indexable, nsphere_tag, comparable_distance_near_tag, N>
+{
+ typedef typename default_distance_result<Point, center_view<const Indexable> >::type result_type;
+
+ inline static result_type apply(Point const& pt, Indexable const& i)
+ {
+ result_type center_dist = math::sqrt( comparable_distance(pt, center_view<const Indexable>(i)) );
+ result_type dist = get_radius<0>(i) < center_dist ? center_dist - get_radius<0>(i) : 0;
+ return dist;
+
+ // return dist * dist to be conformant with comparable_distance?
+ // CONSIDER returning negative value related to the distance or normalized distance to the center if dist < radius
+ }
+};
+
+}}}} // namespace boost::geometry::index::detail
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_NEAR_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/content.hpp b/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/content.hpp
new file mode 100644
index 0000000000..7762c6ac18
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/content.hpp
@@ -0,0 +1,76 @@
+// Boost.Geometry Index
+//
+// n-dimensional content (hypervolume) - 2d area, 3d volume, ...
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
+
+#include <boost/geometry/index/detail/algorithms/content.hpp>
+
+namespace boost { namespace geometry { namespace index { namespace detail {
+
+namespace dispatch {
+
+// TODO replace it by comparable_content?
+// probably radius^Dimension would be sufficient
+// WARNING! this would work only if the same Geometries were compared
+// so it shouldn't be used in the case of Variants!
+// The same with margin()!
+
+template <typename NSphere, size_t Dimension>
+struct content_nsphere
+{
+ BOOST_STATIC_ASSERT(2 < Dimension);
+
+ typedef typename detail::default_content_result<NSphere>::type result_type;
+
+ static inline result_type apply(NSphere const& s)
+ {
+ return (content_nsphere<NSphere, Dimension - 2>::apply(s)
+ * 2 * get_radius<0>(s) * get_radius<0>(s)
+ * ::boost::math::constants::pi<result_type>()) / Dimension;
+ }
+};
+
+template <typename NSphere>
+struct content_nsphere<NSphere, 2>
+{
+ typedef typename detail::default_content_result<NSphere>::type result_type;
+
+ static inline result_type apply(NSphere const& s)
+ {
+ return ::boost::math::constants::pi<result_type>() * get_radius<0>(s) * get_radius<0>(s);
+ }
+};
+
+template <typename NSphere>
+struct content_nsphere<NSphere, 1>
+{
+ typedef typename detail::default_content_result<NSphere>::type result_type;
+
+ static inline result_type apply(NSphere const& s)
+ {
+ return 2 * get_radius<0>(s);
+ }
+};
+
+template <typename Indexable>
+struct content<Indexable, nsphere_tag>
+{
+ static typename default_content_result<Indexable>::type apply(Indexable const& i)
+ {
+ return dispatch::content_nsphere<Indexable, dimension<Indexable>::value>::apply(i);
+ }
+};
+
+} // namespace dispatch
+
+}}}} // namespace boost::geometry::index::detail
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/is_valid.hpp b/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/is_valid.hpp
new file mode 100644
index 0000000000..fec746168e
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/is_valid.hpp
@@ -0,0 +1,33 @@
+// Boost.Geometry Index
+//
+// n-dimensional Indexable validity check
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_DETAIL_ALGORITHMS_IS_VALID_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
+
+#include <boost/geometry/index/detail/algorithms/is_valid.hpp>
+
+namespace boost { namespace geometry { namespace index { namespace detail {
+
+namespace dispatch {
+
+template <typename Indexable>
+struct is_valid<Indexable, nsphere_tag>
+{
+ static inline bool apply(Indexable const& i)
+ {
+ return 0 <= geometry::get_radius<0>(i);
+ }
+};
+
+} // namespace dispatch
+
+}}}} // namespace boost::geometry::index::detail
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/margin.hpp b/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/margin.hpp
new file mode 100644
index 0000000000..c4d8b039a0
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/index/detail/algorithms/margin.hpp
@@ -0,0 +1,59 @@
+// Boost.Geometry Index
+//
+// n-dimensional margin value (hypersurface), 2d perimeter, 3d surface, etc...
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
+
+#include <boost/geometry/index/detail/algorithms/margin.hpp>
+
+namespace boost { namespace geometry { namespace index { namespace detail {
+
+template <typename NSphere, size_t Dimension>
+struct comparable_margin_nsphere
+{
+ BOOST_STATIC_ASSERT(1 < Dimension);
+ //BOOST_STATIC_ASSERT(Dimension <= dimension<NSphere>::value);
+
+ static inline typename default_margin_result<NSphere>::type apply(NSphere const& s)
+ {
+ return comparable_margin_nsphere<NSphere, Dimension-1>::apply(s)
+ * geometry::get_radius<0>(s);
+ }
+};
+
+template <typename NSphere>
+struct comparable_margin_nsphere<NSphere, 1>
+{
+ static inline typename default_margin_result<NSphere>::type apply(NSphere const& )
+ {
+ return 1;
+ }
+};
+
+namespace dispatch {
+
+template <typename NSphere>
+struct comparable_margin<NSphere, nsphere_tag>
+{
+ typedef typename default_margin_result<NSphere>::type result_type;
+
+ static inline result_type apply(NSphere const& g)
+ {
+ return comparable_margin_nsphere<
+ NSphere, dimension<NSphere>::value
+ >::apply(g);
+ }
+};
+
+} // namespace dispatch
+
+}}}} // namespace boost::geometry::index::detail
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/index/detail/indexable.hpp b/3party/boost/boost/geometry/extensions/nsphere/index/detail/indexable.hpp
new file mode 100644
index 0000000000..c82d5e9b4d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/index/detail/indexable.hpp
@@ -0,0 +1,30 @@
+// Boost.Geometry Index
+//
+// Indexable's traits and related functions
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/geometry/index/detail/indexable.hpp>
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_INDEXABLE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_INDEXABLE_HPP
+
+namespace boost { namespace geometry { namespace index { namespace detail {
+
+namespace dispatch {
+
+template <typename Indexable>
+struct point_type<Indexable, geometry::nsphere_tag>
+{
+ typedef typename geometry::traits::point_type<Indexable>::type type;
+};
+
+} // namespace dispatch
+
+}}}} // namespace boost::geometry::index::detail
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_INDEXABLE_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/index/detail/rtree/linear/redistribute_elements.hpp b/3party/boost/boost/geometry/extensions/nsphere/index/detail/rtree/linear/redistribute_elements.hpp
new file mode 100644
index 0000000000..2f57ae890a
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/index/detail/rtree/linear/redistribute_elements.hpp
@@ -0,0 +1,109 @@
+// Boost.Geometry Index
+//
+// R-tree linear split algorithm implementation
+//
+// Copyright (c) 2008 Federico J. Fernandez.
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INDEX_DETAIL_RTREE_LINEAR_REDISTRIBUTE_ELEMENTS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_RTREE_LINEAR_REDISTRIBUTE_ELEMENTS_HPP
+
+#include <boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp>
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree { namespace linear {
+
+template <typename Elements, typename Parameters, typename Translator, size_t DimensionIndex>
+struct find_greatest_normalized_separation<Elements, Parameters, Translator, nsphere_tag, DimensionIndex>
+{
+ typedef typename Elements::value_type element_type;
+ typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
+ typedef typename coordinate_type<indexable_type>::type coordinate_type;
+
+ typedef typename boost::mpl::if_c<
+ boost::is_integral<coordinate_type>::value,
+ double,
+ coordinate_type
+ >::type separation_type;
+
+ static inline void apply(Elements const& elements,
+ Parameters const& parameters,
+ Translator const& translator,
+ separation_type & separation,
+ size_t & seed1,
+ size_t & seed2)
+ {
+ const size_t elements_count = parameters.get_max_elements() + 1;
+ BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected number of elements");
+ BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
+
+ indexable_type const& indexable = rtree::element_indexable(elements[0], translator);
+
+ // find the lowest low, highest high
+ coordinate_type lowest_low = geometry::get<DimensionIndex>(indexable) - geometry::get_radius<0>(indexable);
+ coordinate_type highest_high = geometry::get<DimensionIndex>(indexable) + geometry::get_radius<0>(indexable);
+ // and the lowest high
+ coordinate_type lowest_high = highest_high;
+ size_t lowest_high_index = 0;
+ for ( size_t i = 1 ; i < elements_count ; ++i )
+ {
+ indexable_type const& indexable = rtree::element_indexable(elements[i], translator);
+
+ coordinate_type min_coord = geometry::get<DimensionIndex>(indexable) - geometry::get_radius<0>(indexable);
+ coordinate_type max_coord = geometry::get<DimensionIndex>(indexable) + geometry::get_radius<0>(indexable);
+
+ if ( max_coord < lowest_high )
+ {
+ lowest_high = max_coord;
+ lowest_high_index = i;
+ }
+
+ if ( min_coord < lowest_low )
+ lowest_low = min_coord;
+
+ if ( highest_high < max_coord )
+ highest_high = max_coord;
+ }
+
+ // find the highest low
+ size_t highest_low_index = lowest_high_index == 0 ? 1 : 0;
+ indexable_type const& highest_low_indexable = rtree::element_indexable(elements[highest_low_index], translator);
+ coordinate_type highest_low = geometry::get<DimensionIndex>(highest_low_indexable) - geometry::get_radius<0>(highest_low_indexable);
+ for ( size_t i = highest_low_index ; i < elements_count ; ++i )
+ {
+ indexable_type const& indexable = rtree::element_indexable(elements[i], translator);
+
+ coordinate_type min_coord = geometry::get<DimensionIndex>(indexable) - geometry::get_radius<0>(indexable);
+ if ( highest_low < min_coord &&
+ i != lowest_high_index )
+ {
+ highest_low = min_coord;
+ highest_low_index = i;
+ }
+ }
+
+ coordinate_type const width = highest_high - lowest_low;
+
+ // highest_low - lowest_high
+ separation = difference<separation_type>(lowest_high, highest_low);
+ // BOOST_GEOMETRY_INDEX_ASSERT(0 <= width);
+ if ( std::numeric_limits<coordinate_type>::epsilon() < width )
+ separation /= width;
+
+ seed1 = highest_low_index;
+ seed2 = lowest_high_index;
+
+ ::boost::ignore_unused_variable_warning(parameters);
+ }
+};
+
+}}} // namespace detail::rtree::linear
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_RTREE_LINEAR_REDISTRIBUTE_ELEMENTS_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/index/detail/rtree/rstar/redistribute_elements.hpp b/3party/boost/boost/geometry/extensions/nsphere/index/detail/rtree/rstar/redistribute_elements.hpp
new file mode 100644
index 0000000000..01d6d3847c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/index/detail/rtree/rstar/redistribute_elements.hpp
@@ -0,0 +1,74 @@
+// Boost.Geometry Index
+//
+// R-tree R*-tree split algorithm implementation
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INDEX_DETAIL_RTREE_RSTAR_REDISTRIBUTE_ELEMENTS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_RTREE_RSTAR_REDISTRIBUTE_ELEMENTS_HPP
+
+#include <boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp>
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree { namespace rstar {
+
+template <typename Element, typename Translator, size_t AxisIndex>
+class element_axis_corner_less<Element, Translator, nsphere_tag, min_corner, AxisIndex>
+{
+public:
+ element_axis_corner_less(Translator const& tr)
+ : m_tr(tr)
+ {}
+
+ bool operator()(Element const& e1, Element const& e2) const
+ {
+ typedef typename rtree::element_indexable_type<Element, Translator>::type indexable_type;
+ indexable_type const& i1 = rtree::element_indexable(e1, m_tr);
+ indexable_type const& i2 = rtree::element_indexable(e2, m_tr);
+
+ return geometry::get<AxisIndex>(i1) - get_radius<0>(i1)
+ < geometry::get<AxisIndex>(i2) - get_radius<0>(i2);
+ }
+
+private:
+ Translator const& m_tr;
+};
+
+template <typename Element, typename Translator, size_t AxisIndex>
+class element_axis_corner_less<Element, Translator, nsphere_tag, max_corner, AxisIndex>
+{
+public:
+ element_axis_corner_less(Translator const& tr)
+ : m_tr(tr)
+ {}
+
+ bool operator()(Element const& e1, Element const& e2) const
+ {
+ typedef typename rtree::element_indexable_type<Element, Translator>::type indexable_type;
+ indexable_type const& i1 = rtree::element_indexable(e1, m_tr);
+ indexable_type const& i2 = rtree::element_indexable(e2, m_tr);
+
+ return geometry::get<AxisIndex>(i1) + get_radius<0>(i1)
+ < geometry::get<AxisIndex>(i2) + get_radius<0>(i2);
+ }
+
+private:
+ Translator const& m_tr;
+};
+
+template <typename Box, size_t AxisIndex>
+struct choose_split_axis_and_index_for_axis<Box, AxisIndex, nsphere_tag>
+ : choose_split_axis_and_index_for_axis<Box, AxisIndex, box_tag>
+{};
+
+
+}}} // namespace detail::rtree::rstar
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_RTREE_RSTAR_REDISTRIBUTE_ELEMENTS_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/index/indexable.hpp b/3party/boost/boost/geometry/extensions/nsphere/index/indexable.hpp
new file mode 100644
index 0000000000..19b5de8dc3
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/index/indexable.hpp
@@ -0,0 +1,25 @@
+// Boost.Geometry Index
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_INDEX_INDEXABLE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_INDEXABLE_HPP
+
+#include <boost/geometry/index/indexable.hpp>
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail {
+
+template <typename NSphere>
+struct is_indexable_impl<NSphere, geometry::nsphere_tag> { static const bool value = true; };
+
+} // namespace detail
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_INDEXABLE_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/nsphere.hpp b/3party/boost/boost/geometry/extensions/nsphere/nsphere.hpp
new file mode 100644
index 0000000000..f9cf82e19d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/nsphere.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_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/disjoint.hpp>
+#include <boost/geometry/extensions/nsphere/strategies/cartesian/nsphere_in_box.hpp>
+#include <boost/geometry/extensions/nsphere/strategies/cartesian/point_in_nsphere.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/within.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/covered_by.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/expand.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/equals.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/centroid.hpp>
+
+#include <boost/geometry/extensions/nsphere/index/indexable.hpp>
+#include <boost/geometry/extensions/nsphere/index/detail/algorithms/content.hpp>
+#include <boost/geometry/extensions/nsphere/index/detail/algorithms/is_valid.hpp>
+#include <boost/geometry/extensions/nsphere/index/detail/algorithms/margin.hpp>
+#include <boost/geometry/extensions/nsphere/index/detail/algorithms/comparable_distance_near.hpp>
+#include <boost/geometry/extensions/nsphere/index/detail/algorithms/bounds.hpp>
+
+#include <boost/geometry/index/detail/exception.hpp> // needed by the following
+#include <boost/geometry/index/detail/rtree/options.hpp> // needed by the following
+#include <boost/geometry/index/detail/translator.hpp> // needed by the following
+#include <boost/geometry/extensions/nsphere/index/detail/rtree/linear/redistribute_elements.hpp>
+#include <boost/geometry/extensions/nsphere/index/detail/rtree/rstar/redistribute_elements.hpp>
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/strategies/cartesian/nsphere_in_box.hpp b/3party/boost/boost/geometry/extensions/nsphere/strategies/cartesian/nsphere_in_box.hpp
new file mode 100644
index 0000000000..1086126f8d
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/strategies/cartesian/nsphere_in_box.hpp
@@ -0,0 +1,175 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_STRATEGIES_CARTESIAN_NSPHERE_IN_BOX_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_STRATEGIES_CARTESIAN_NSPHERE_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 nsphere_within_range
+{
+ template <typename ContainedValue, typename ContainingValue>
+ static inline bool apply(ContainedValue const& ed_min
+ , ContainedValue const& ed_max
+ , ContainingValue const& ing_min
+ , ContainingValue const& ing_max)
+ {
+ return ing_min < ed_min && ed_max < ing_max;
+ }
+};
+
+
+struct nsphere_covered_by_range
+{
+ template <typename ContainedValue, typename ContainingValue>
+ static inline bool apply(ContainedValue const& ed_min
+ , ContainedValue const& ed_max
+ , ContainingValue const& ing_min
+ , ContainingValue const& ing_max)
+ {
+ return ing_min <= ed_min && ed_max <= ing_max;
+ }
+};
+
+template
+<
+ typename SubStrategy,
+ typename NSphere,
+ typename Box,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct relate_nsphere_box_loop
+{
+ static inline bool apply(NSphere const& sphere, Box const& box)
+ {
+ if (! SubStrategy::apply(
+ get<Dimension>(sphere) - get_radius<0>(sphere),
+ get<Dimension>(sphere) + get_radius<0>(sphere),
+ get<min_corner, Dimension>(box),
+ get<max_corner, Dimension>(box))
+ )
+ {
+ return false;
+ }
+
+ return relate_nsphere_box_loop
+ <
+ SubStrategy,
+ NSphere, Box,
+ Dimension + 1, DimensionCount
+ >::apply(sphere, box);
+ }
+};
+
+
+template
+<
+ typename SubStrategy,
+ typename NSphere,
+ typename Box,
+ std::size_t DimensionCount
+>
+struct relate_nsphere_box_loop<SubStrategy, NSphere, Box, DimensionCount, DimensionCount>
+{
+ static inline bool apply(NSphere const& , Box const& )
+ {
+ return true;
+ }
+};
+
+
+template
+<
+ typename NSphere,
+ typename Box,
+ typename SubStrategy = nsphere_within_range
+>
+struct nsphere_in_box
+{
+ static inline bool apply(NSphere const& nsphere, Box const& box)
+ {
+ return relate_nsphere_box_loop
+ <
+ SubStrategy,
+ NSphere, Box,
+ 0, dimension<NSphere>::type::value
+ >::apply(nsphere, box);
+ }
+};
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename NSphere, typename Box>
+struct default_strategy
+ <
+ nsphere_tag, box_tag,
+ nsphere_tag, areal_tag,
+ cartesian_tag, cartesian_tag,
+ NSphere, Box
+ >
+{
+ typedef within::nsphere_in_box<NSphere, Box, within::nsphere_within_range> type;
+};
+
+
+}} // namespace within::services
+
+
+namespace covered_by { namespace services
+{
+
+
+template <typename NSphere, typename Box>
+struct default_strategy
+ <
+ nsphere_tag, box_tag,
+ nsphere_tag, areal_tag,
+ cartesian_tag, cartesian_tag,
+ NSphere, Box
+ >
+{
+ typedef within::nsphere_in_box<NSphere, Box, within::nsphere_covered_by_range> type;
+};
+
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_STRATEGIES_CARTESIAN_NSPHERE_IN_BOX_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/strategies/cartesian/point_in_nsphere.hpp b/3party/boost/boost/geometry/extensions/nsphere/strategies/cartesian/point_in_nsphere.hpp
new file mode 100644
index 0000000000..3ebed5ab0c
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/strategies/cartesian/point_in_nsphere.hpp
@@ -0,0 +1,147 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_STRATEGIES_CARTESIAN_POINT_IN_NSPHERE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_STRATEGIES_CARTESIAN_POINT_IN_NSPHERE_HPP
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+#include <boost/geometry/extensions/nsphere/views/center_view.hpp>
+
+namespace boost { namespace geometry { namespace strategy
+{
+
+namespace within
+{
+
+struct point_nsphere_within_comparable_distance
+{
+ template <typename ComparableDistance, typename Radius>
+ static inline bool apply(ComparableDistance const& ed_comp_dist
+ , Radius const& ing_radius)
+ {
+ return ed_comp_dist < ing_radius * ing_radius;
+ }
+};
+
+
+struct point_nsphere_covered_by_comparable_distance
+{
+ template <typename ComparableDistance, typename Radius>
+ static inline bool apply(ComparableDistance const& ed_comp_dist
+ , Radius const& ing_radius)
+ {
+ return ed_comp_dist <= ing_radius * ing_radius;
+ }
+};
+
+template
+<
+ typename Point,
+ typename NSphere,
+ typename SubStrategy = point_nsphere_within_comparable_distance
+>
+struct point_in_nsphere
+{
+ static inline bool apply(Point const& point, NSphere const& nsphere)
+ {
+ return SubStrategy::apply(
+ geometry::comparable_distance(point, center_view<NSphere const>(nsphere)),
+ get_radius<0>(nsphere));
+ }
+};
+
+
+//// For many geometry-in-nsphere, we do not have a strategy yet... but a default strategy should exist
+//struct nsphere_dummy
+//{
+// template <typename A, typename B>
+// static bool apply(A const& a, B const& b)
+// {
+// // Assertion if called
+// BOOST_GEOMETRY_ASSERT(false);
+// return false;
+// }
+//};
+
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename Point, typename NSphere>
+struct default_strategy
+ <
+ point_tag, nsphere_tag,
+ point_tag, nsphere_tag,
+ cartesian_tag, cartesian_tag,
+ Point, NSphere
+ >
+{
+ typedef within::point_in_nsphere<Point, NSphere, within::point_nsphere_within_comparable_distance> type;
+};
+
+//template <typename AnyTag, typename AnyGeometry, typename NSphere>
+//struct default_strategy
+// <
+// AnyTag, nsphere_tag,
+// AnyTag, nsphere_tag,
+// cartesian_tag, cartesian_tag,
+// AnyGeometry, NSphere
+// >
+//{
+// typedef within::nsphere_dummy type;
+//};
+
+
+}} // namespace within::services
+
+
+namespace covered_by { namespace services
+{
+
+
+template <typename Point, typename NSphere>
+struct default_strategy
+ <
+ point_tag, nsphere_tag,
+ point_tag, nsphere_tag,
+ cartesian_tag, cartesian_tag,
+ Point, NSphere
+ >
+{
+ typedef within::point_in_nsphere<Point, NSphere, within::point_nsphere_covered_by_comparable_distance> type;
+};
+
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_STRATEGIES_CARTESIAN_NSPHERE_IN_BOX_HPP
diff --git a/3party/boost/boost/geometry/extensions/nsphere/views/center_view.hpp b/3party/boost/boost/geometry/extensions/nsphere/views/center_view.hpp
new file mode 100644
index 0000000000..44bc126020
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/nsphere/views/center_view.hpp
@@ -0,0 +1,105 @@
+// 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.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_VIEWS_CENTER_VIEW_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_VIEWS_CENTER_VIEW_HPP
+
+#include <boost/geometry/core/point_type.hpp>
+
+namespace boost { namespace geometry
+{
+
+// Silence warning C4512: assignment operator could not be generated
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4512)
+#endif
+
+template <typename NSphere>
+struct center_view
+{
+ typedef typename geometry::point_type<NSphere>::type point_type;
+ typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
+
+ explicit center_view(NSphere & nsphere)
+ : m_nsphere(nsphere)
+ {}
+
+ template <std::size_t I> coordinate_type get() const { return geometry::get<I>(m_nsphere); }
+ template <std::size_t I> void set(coordinate_type const& v) { geometry::set<I>(m_nsphere, v); }
+
+private :
+ NSphere & m_nsphere;
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template<typename NSphere>
+struct tag< center_view<NSphere> >
+{
+ typedef point_tag type;
+};
+
+template<typename NSphere>
+struct coordinate_type< center_view<NSphere> >
+{
+ typedef typename geometry::coordinate_type<
+ typename geometry::point_type<NSphere>::type
+ >::type type;
+};
+
+template<typename NSphere>
+struct coordinate_system< center_view<NSphere> >
+{
+ typedef typename geometry::coordinate_system<
+ typename geometry::point_type<NSphere>::type
+ >::type type;
+};
+
+template<typename NSphere>
+struct dimension< center_view<NSphere> >
+ : geometry::dimension< typename geometry::point_type<NSphere>::type >
+{};
+
+template<typename NSphere, std::size_t Dimension>
+struct access<center_view<NSphere>, Dimension>
+{
+ typedef typename geometry::coordinate_type<
+ typename geometry::point_type<NSphere>::type
+ >::type coordinate_type;
+
+ static inline coordinate_type get(center_view<NSphere> const& p)
+ {
+ return p.template get<Dimension>();
+ }
+
+ static inline void set(center_view<NSphere> & p, coordinate_type const& value)
+ {
+ p.template set<Dimension>(value);
+ }
+};
+
+}
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_VIEWS_CENTER_VIEW_HPP
diff --git a/3party/boost/boost/geometry/extensions/strategies/cartesian/distance_info.hpp b/3party/boost/boost/geometry/extensions/strategies/cartesian/distance_info.hpp
new file mode 100644
index 0000000000..0f442de15e
--- /dev/null
+++ b/3party/boost/boost/geometry/extensions/strategies/cartesian/distance_info.hpp
@@ -0,0 +1,180 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2013 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2013 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2013 Mateusz Loskot, London, UK.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_CARTESIAN_DISTANCE_INFO_HPP
+#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_DISTANCE_INFO_HPP
+
+#include <boost/type_traits/remove_const.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>
+
+#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+template <typename Point>
+struct distance_info_result
+{
+ typedef Point point_type;
+ typedef typename default_distance_result<Point>::type distance_type;
+
+ bool on_segment;
+ bool within_geometry;
+ distance_type real_distance;
+ Point projected_point1; // A on B
+ Point projected_point2; // B on A
+ distance_type projected_distance1;
+ distance_type projected_distance2;
+ distance_type fraction1;
+ distance_type fraction2;
+ segment_identifier seg_id1;
+ segment_identifier seg_id2;
+
+ inline distance_info_result()
+ : on_segment(false)
+ , within_geometry(false)
+ , real_distance(distance_type())
+ , projected_distance1(distance_type())
+ , projected_distance2(distance_type())
+ , fraction1(distance_type())
+ , fraction2(distance_type())
+ {}
+};
+
+
+namespace strategy { namespace distance
+{
+
+template
+<
+ typename CalculationType = void,
+ typename Strategy = pythagoras<CalculationType>
+>
+struct calculate_distance_info
+{
+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.
+ template <typename Point, typename PointOfSegment>
+ struct calculation_type
+ : promote_floating_point
+ <
+ typename strategy::distance::services::return_type
+ <
+ Strategy,
+ Point,
+ PointOfSegment
+ >::type
+ >
+ {};
+
+
+public :
+
+ // Helper function
+ template <typename Point1, typename Point2>
+ inline typename calculation_type<Point1, Point2>::type
+ apply_point_point(Point1 const& p1, Point2 const& p2) const
+ {
+ Strategy point_point_strategy;
+ boost::ignore_unused_variable_warning(point_point_strategy);
+ return point_point_strategy.apply(p1, p2);
+ }
+
+ template <typename Point, typename PointOfSegment, typename Result>
+ inline void apply(Point const& p,
+ PointOfSegment const& p1, PointOfSegment const& p2,
+ Result& result) const
+ {
+ assert_dimension_equal<Point, PointOfSegment>();
+
+ typedef typename calculation_type<Point, PointOfSegment>::type calculation_type;
+
+ //// 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;
+
+
+
+ // For source-code-comments, see "cartesian/distance_distance_info.hpp"
+ fp_vector_type v, w;
+
+ geometry::convert(p2, v);
+ geometry::convert(p, w);
+ subtract_point(v, p1);
+ subtract_point(w, p1);
+
+ calculation_type const zero = calculation_type();
+
+ calculation_type const c1 = dot_product(w, v);
+ calculation_type const c2 = dot_product(v, v);
+
+ result.on_segment = c1 >= zero && c1 <= c2;
+
+ Strategy point_point_strategy;
+ boost::ignore_unused_variable_warning(point_point_strategy);
+
+ if (geometry::math::equals(c2, zero))
+ {
+ geometry::convert(p1, result.projected_point1);
+ result.fraction1 = 0.0;
+ result.on_segment = false;
+ result.projected_distance1 = result.real_distance = apply_point_point(p, p1);
+ return;
+ }
+
+ calculation_type const b = c1 / c2;
+ result.fraction1 = b;
+
+ geometry::convert(p1, result.projected_point1);
+ multiply_value(v, b);
+ add_point(result.projected_point1, v);
+ result.projected_distance1 = apply_point_point(p, result.projected_point1);
+ result.real_distance
+ = c1 < zero ? apply_point_point(p, p1)
+ : c1 > c2 ? apply_point_point(p, p2)
+ : result.projected_distance1;
+ }
+};
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_DISTANCE_INFO_HPP
diff --git a/3party/boost/boost/geometry/extensions/strategies/parse.hpp b/3party/boost/boost/geometry/extensions/strategies/parse.hpp
new file mode 100644
index 0000000000..de0cdc2ab9
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/util/get_cs_as_radian.hpp b/3party/boost/boost/geometry/extensions/util/get_cs_as_radian.hpp
new file mode 100644
index 0000000000..03a20e55b7
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/util/replace_point_type.hpp b/3party/boost/boost/geometry/extensions/util/replace_point_type.hpp
new file mode 100644
index 0000000000..f1300f2da9
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/views/enveloped_view.hpp b/3party/boost/boost/geometry/extensions/views/enveloped_view.hpp
new file mode 100644
index 0000000000..0e654cd6fd
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/extensions/views/section_view.hpp b/3party/boost/boost/geometry/extensions/views/section_view.hpp
new file mode 100644
index 0000000000..8e0dcce504
--- /dev/null
+++ b/3party/boost/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/3party/boost/boost/geometry/geometries/adapted/boost_fusion.hpp b/3party/boost/boost/geometry/geometries/adapted/boost_fusion.hpp
index a9aba916a5..2f3594e4e7 100644
--- a/3party/boost/boost/geometry/geometries/adapted/boost_fusion.hpp
+++ b/3party/boost/boost/geometry/geometries/adapted/boost_fusion.hpp
@@ -1,7 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2011-2012 Akira Takahashi
-// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2011-2015 Akira Takahashi
+// Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,23 +18,24 @@
#include <cstddef>
+#include <boost/core/enable_if.hpp>
+
#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/and.hpp>
#include <boost/mpl/count_if.hpp>
+#include <boost/mpl/front.hpp>
+#include <boost/mpl/placeholders.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>
@@ -65,7 +71,7 @@ struct is_coordinate_size : boost::mpl::bool_<
template<typename Sequence>
struct is_fusion_sequence
- : mpl::and_<boost::fusion::traits::is_sequence<Sequence>,
+ : boost::mpl::and_<boost::fusion::traits::is_sequence<Sequence>,
fusion_adapt_detail::is_coordinate_size<Sequence>,
fusion_adapt_detail::all_same<Sequence> >
{};
diff --git a/3party/boost/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp b/3party/boost/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp
index 825ef8061f..1616369da1 100644
--- a/3party/boost/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp
+++ b/3party/boost/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp
@@ -150,7 +150,7 @@ public :
}
}
- void resize(std::size_t new_size)
+ void resize(std::size_t /*new_size*/)
{
if (m_do_hole)
{
diff --git a/3party/boost/boost/geometry/geometries/box.hpp b/3party/boost/boost/geometry/geometries/box.hpp
index a2e3d4fd79..97a4ba06da 100644
--- a/3party/boost/boost/geometry/geometries/box.hpp
+++ b/3party/boost/boost/geometry/geometries/box.hpp
@@ -17,10 +17,14 @@
#include <cstddef>
#include <boost/concept/assert.hpp>
+#include <boost/config.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+#include <boost/geometry/core/assert.hpp>
+#endif
namespace boost { namespace geometry
@@ -29,18 +33,21 @@ 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.
+\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.
+
+\qbk{[include reference/geometries/box.qbk]}
+\qbk{before.synopsis, [heading Model of]}
+\qbk{before.synopsis, [link geometry.reference.concepts.concept_box Box Concept]}
*/
template<typename Point>
@@ -50,7 +57,25 @@ class box
public:
- inline box() {}
+#if !defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ /// \constructor_default_no_init
+ box() = default;
+#else
+ /// \constructor_default_no_init
+ inline box()
+ {}
+#endif
+#else // defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ inline box()
+ {
+ m_created = 1;
+ }
+ ~box()
+ {
+ m_created = 0;
+ }
+#endif
/*!
\brief Constructor taking the minimum corner point and the maximum corner point
@@ -59,18 +84,50 @@ public:
{
geometry::convert(min_corner, m_min_corner);
geometry::convert(max_corner, m_max_corner);
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ m_created = 1;
+#endif
}
- inline Point const& min_corner() const { return m_min_corner; }
- inline Point const& max_corner() const { return m_max_corner; }
+ inline Point const& min_corner() const
+ {
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+#endif
+ return m_min_corner;
+ }
+ inline Point const& max_corner() const
+ {
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+#endif
+ return m_max_corner;
+ }
- inline Point& min_corner() { return m_min_corner; }
- inline Point& max_corner() { return m_max_corner; }
+ inline Point& min_corner()
+ {
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+#endif
+ return m_min_corner;
+ }
+ inline Point& max_corner()
+ {
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+#endif
+ return m_max_corner;
+ }
private:
Point m_min_corner;
Point m_max_corner;
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ int m_created;
+#endif
};
diff --git a/3party/boost/boost/geometry/geometries/concepts/point_concept.hpp b/3party/boost/boost/geometry/geometries/concepts/point_concept.hpp
index 1e1b31e61f..db49771129 100644
--- a/3party/boost/boost/geometry/geometries/concepts/point_concept.hpp
+++ b/3party/boost/boost/geometry/geometries/concepts/point_concept.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -17,6 +22,7 @@
#include <cstddef>
#include <boost/concept_check.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
@@ -24,7 +30,6 @@
-
namespace boost { namespace geometry { namespace concept
{
@@ -46,6 +51,9 @@ The point concept is defined as following:
with two functions:
- \b get to get a coordinate value
- \b set to set a coordinate value (this one is not checked for ConstPoint)
+- for non-Cartesian coordinate systems, the coordinate system's units
+ must either be boost::geometry::degree or boost::geometry::radian
+
\par Example:
@@ -90,8 +98,12 @@ class Point
typedef typename coordinate_type<Geometry>::type ctype;
typedef typename coordinate_system<Geometry>::type csystem;
- enum { ccount = dimension<Geometry>::value };
+ // The following enum is used to fully instantiate the coordinate
+ // system class; this is needed in order to check the units passed
+ // to it for non-Cartesian coordinate systems.
+ enum { cs_check = sizeof(csystem) };
+ enum { ccount = dimension<Geometry>::value };
template <typename P, std::size_t Dimension, std::size_t DimensionCount>
struct dimension_checker
@@ -139,8 +151,12 @@ class ConstPoint
typedef typename coordinate_type<Geometry>::type ctype;
typedef typename coordinate_system<Geometry>::type csystem;
- enum { ccount = dimension<Geometry>::value };
+ // The following enum is used to fully instantiate the coordinate
+ // system class; this is needed in order to check the units passed
+ // to it for non-Cartesian coordinate systems.
+ enum { cs_check = sizeof(csystem) };
+ enum { ccount = dimension<Geometry>::value };
template <typename P, std::size_t Dimension, std::size_t DimensionCount>
struct dimension_checker
@@ -149,7 +165,7 @@ class ConstPoint
{
const P* p = 0;
ctype coord(geometry::get<Dimension>(*p));
- boost::ignore_unused_variable_warning(coord);
+ boost::ignore_unused(coord);
dimension_checker<P, Dimension+1, DimensionCount>::apply();
}
};
diff --git a/3party/boost/boost/geometry/geometries/helper_geometry.hpp b/3party/boost/boost/geometry/geometries/helper_geometry.hpp
new file mode 100644
index 0000000000..9cf14a9117
--- /dev/null
+++ b/3party/boost/boost/geometry/geometries/helper_geometry.hpp
@@ -0,0 +1,162 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_HELPER_GEOMETRY_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_HELPER_GEOMETRY_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/point_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/geometries/point.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace helper_geometries
+{
+
+template <typename Geometry, typename CS_Tag = typename cs_tag<Geometry>::type>
+struct default_units
+{
+ typedef typename coordinate_system<Geometry>::type::units type;
+};
+
+// The Cartesian coordinate system does not define the type units.
+// For that reason the generic implementation for default_units cannot be used
+// and specialization needs to be defined.
+// Moreover, it makes sense to define the units for the Cartesian
+// coordinate system to be radians, as this way a Cartesian point can
+// potentially be used in algorithms taking non-Cartesian strategies
+// and work as if it was as point in the non-Cartesian coordinate
+// system with radian units.
+template <typename Geometry>
+struct default_units<Geometry, cartesian_tag>
+{
+ typedef radian type;
+};
+
+
+template <typename Units, typename CS_Tag>
+struct cs_tag_to_coordinate_system
+{
+ typedef cs::cartesian type;
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, spherical_equatorial_tag>
+{
+ typedef cs::spherical_equatorial<Units> type;
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, spherical_tag>
+{
+ typedef cs::spherical<Units> type;
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, geographic_tag>
+{
+ typedef cs::geographic<Units> type;
+};
+
+
+template
+<
+ typename Point,
+ typename NewCoordinateType,
+ typename NewUnits,
+ typename CS_Tag = typename cs_tag<Point>::type
+>
+struct helper_point
+{
+ typedef model::point
+ <
+ NewCoordinateType,
+ dimension<Point>::value,
+ typename cs_tag_to_coordinate_system<NewUnits, CS_Tag>::type
+ > type;
+};
+
+
+}} // detail::helper_geometries
+
+
+namespace detail_dispatch
+{
+
+
+template
+<
+ typename Geometry,
+ typename NewCoordinateType,
+ typename NewUnits,
+ typename Tag = typename tag<Geometry>::type>
+struct helper_geometry : not_implemented<Geometry>
+{};
+
+
+template <typename Point, typename NewCoordinateType, typename NewUnits>
+struct helper_geometry<Point, NewCoordinateType, NewUnits, point_tag>
+{
+ typedef typename detail::helper_geometries::helper_point
+ <
+ Point, NewCoordinateType, NewUnits
+ >::type type;
+};
+
+
+template <typename Box, typename NewCoordinateType, typename NewUnits>
+struct helper_geometry<Box, NewCoordinateType, NewUnits, box_tag>
+{
+ typedef model::box
+ <
+ typename helper_geometry
+ <
+ typename point_type<Box>::type, NewCoordinateType, NewUnits
+ >::type
+ > type;
+};
+
+
+} // detail_dispatch
+
+
+// Meta-function that provides a new helper geometry of the same kind as
+// the input geometry and the same coordinate system type,
+// but with a possibly different coordinate type and coordinate system units
+template
+<
+ typename Geometry,
+ typename NewCoordinateType = typename coordinate_type<Geometry>::type,
+ typename NewUnits = typename detail::helper_geometries::default_units
+ <
+ Geometry
+ >::type
+>
+struct helper_geometry
+{
+ typedef typename detail_dispatch::helper_geometry
+ <
+ Geometry, NewCoordinateType, NewUnits
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_HELPER_GEOMETRY_HPP
diff --git a/3party/boost/boost/geometry/geometries/linestring.hpp b/3party/boost/boost/geometry/geometries/linestring.hpp
index 38bc3d4c49..22c9c99de9 100644
--- a/3party/boost/boost/geometry/geometries/linestring.hpp
+++ b/3party/boost/boost/geometry/geometries/linestring.hpp
@@ -3,6 +3,7 @@
// 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.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -25,6 +26,10 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/config.hpp>
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#include <initializer_list>
+#endif
namespace boost { namespace geometry
{
@@ -39,6 +44,7 @@ namespace model
\tparam Container \tparam_container
\tparam Allocator \tparam_allocator
+\qbk{[include reference/geometries/linestring.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_linestring Linestring Concept]
@@ -68,6 +74,28 @@ public :
inline linestring(Iterator begin, Iterator end)
: base_type(begin, end)
{}
+
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+
+ /// \constructor_initializer_list{linestring}
+ inline linestring(std::initializer_list<Point> l)
+ : base_type(l.begin(), l.end())
+ {}
+
+// Commented out for now in order to support Boost.Assign
+// Without this assignment operator first the object should be created
+// from initializer list, then it should be moved.
+//// Without this workaround in MSVC the assignment operator is ambiguous
+//#ifndef BOOST_MSVC
+// /// \assignment_initializer_list{linestring}
+// inline linestring & operator=(std::initializer_list<Point> l)
+// {
+// base_type::assign(l.begin(), l.end());
+// return *this;
+// }
+//#endif
+
+#endif
};
} // namespace model
diff --git a/3party/boost/boost/geometry/geometries/multi_linestring.hpp b/3party/boost/boost/geometry/geometries/multi_linestring.hpp
index 2ba8e7196b..cd08fdbe14 100644
--- a/3party/boost/boost/geometry/geometries/multi_linestring.hpp
+++ b/3party/boost/boost/geometry/geometries/multi_linestring.hpp
@@ -3,6 +3,7 @@
// 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.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -22,6 +23,10 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/linestring_concept.hpp>
+#include <boost/config.hpp>
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#include <initializer_list>
+#endif
namespace boost { namespace geometry
{
@@ -36,6 +41,7 @@ namespace model
e.g. a highway (with interruptions)
\ingroup geometries
+\qbk{[include reference/geometries/multi_linestring.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_multi_linestring MultiLineString Concept]
@@ -50,6 +56,39 @@ template
class multi_linestring : public Container<LineString, Allocator<LineString> >
{
BOOST_CONCEPT_ASSERT( (concept::Linestring<LineString>) );
+
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+
+ // default constructor and base_type definitions are required only
+ // if the constructor taking std::initializer_list is defined
+
+ typedef Container<LineString, Allocator<LineString> > base_type;
+
+public:
+ /// \constructor_default{multi_linestring}
+ multi_linestring()
+ : base_type()
+ {}
+
+ /// \constructor_initializer_list{multi_linestring}
+ inline multi_linestring(std::initializer_list<LineString> l)
+ : base_type(l.begin(), l.end())
+ {}
+
+// Commented out for now in order to support Boost.Assign
+// Without this assignment operator first the object should be created
+// from initializer list, then it shoudl be moved.
+//// Without this workaround in MSVC the assignment operator is ambiguous
+//#ifndef BOOST_MSVC
+// /// \assignment_initializer_list{multi_linestring}
+// inline multi_linestring & operator=(std::initializer_list<LineString> l)
+// {
+// base_type::assign(l.begin(), l.end());
+// return *this;
+// }
+//#endif
+
+#endif
};
diff --git a/3party/boost/boost/geometry/geometries/multi_point.hpp b/3party/boost/boost/geometry/geometries/multi_point.hpp
index d0a782a1de..ab4cd88177 100644
--- a/3party/boost/boost/geometry/geometries/multi_point.hpp
+++ b/3party/boost/boost/geometry/geometries/multi_point.hpp
@@ -3,6 +3,7 @@
// 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.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -22,6 +23,10 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/config.hpp>
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#include <initializer_list>
+#endif
namespace boost { namespace geometry
{
@@ -38,6 +43,8 @@ namespace model
\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{[include reference/geometries/multi_point.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_multi_point MultiPoint Concept]
@@ -66,6 +73,28 @@ public :
inline multi_point(Iterator begin, Iterator end)
: base_type(begin, end)
{}
+
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+
+ /// \constructor_initializer_list{multi_point}
+ inline multi_point(std::initializer_list<Point> l)
+ : base_type(l.begin(), l.end())
+ {}
+
+// Commented out for now in order to support Boost.Assign
+// Without this assignment operator first the object should be created
+// from initializer list, then it shoudl be moved.
+//// Without this workaround in MSVC the assignment operator is ambiguous
+//#ifndef BOOST_MSVC
+// /// \assignment_initializer_list{multi_point}
+// inline multi_point & operator=(std::initializer_list<Point> l)
+// {
+// base_type::assign(l.begin(), l.end());
+// return *this;
+// }
+//#endif
+
+#endif
};
} // namespace model
diff --git a/3party/boost/boost/geometry/geometries/multi_polygon.hpp b/3party/boost/boost/geometry/geometries/multi_polygon.hpp
index 228074cd34..9db74b4ec4 100644
--- a/3party/boost/boost/geometry/geometries/multi_polygon.hpp
+++ b/3party/boost/boost/geometry/geometries/multi_polygon.hpp
@@ -3,6 +3,7 @@
// 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.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -22,6 +23,11 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/polygon_concept.hpp>
+#include <boost/config.hpp>
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#include <initializer_list>
+#endif
+
namespace boost { namespace geometry
{
@@ -34,6 +40,7 @@ namespace model
e.g. Hawaii
\ingroup geometries
+\qbk{[include reference/geometries/multi_polygon.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_multi_polygon MultiPolygon Concept]
@@ -48,6 +55,39 @@ template
class multi_polygon : public Container<Polygon, Allocator<Polygon> >
{
BOOST_CONCEPT_ASSERT( (concept::Polygon<Polygon>) );
+
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+
+ // default constructor and base_type definitions are required only
+ // if the constructor taking std::initializer_list is defined
+
+ typedef Container<Polygon, Allocator<Polygon> > base_type;
+
+public:
+ /// \constructor_default{multi_polygon}
+ multi_polygon()
+ : base_type()
+ {}
+
+ /// \constructor_initializer_list{multi_polygon}
+ inline multi_polygon(std::initializer_list<Polygon> l)
+ : base_type(l.begin(), l.end())
+ {}
+
+// Commented out for now in order to support Boost.Assign
+// Without this assignment operator first the object should be created
+// from initializer list, then it shoudl be moved.
+//// Without this workaround in MSVC the assignment operator is ambiguous
+//#ifndef BOOST_MSVC
+// /// \assignment_initializer_list{multi_polygon}
+// inline multi_polygon & operator=(std::initializer_list<Polygon> l)
+// {
+// base_type::assign(l.begin(), l.end());
+// return *this;
+// }
+//#endif
+
+#endif
};
diff --git a/3party/boost/boost/geometry/geometries/point.hpp b/3party/boost/boost/geometry/geometries/point.hpp
index a25340c463..70bfeed447 100644
--- a/3party/boost/boost/geometry/geometries/point.hpp
+++ b/3party/boost/boost/geometry/geometries/point.hpp
@@ -1,8 +1,14 @@
// 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.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -16,14 +22,20 @@
#include <cstddef>
+#include <boost/config.hpp>
+#include <boost/mpl/assert.hpp>
#include <boost/mpl/int.hpp>
-#include <boost/static_assert.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.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>
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+#include <algorithm>
+#include <boost/geometry/core/assert.hpp>
+#endif
namespace boost { namespace geometry
{
@@ -38,6 +50,37 @@ namespace boost { namespace geometry
namespace model
{
+namespace detail
+{
+
+template <std::size_t DimensionCount, std::size_t Index>
+struct array_assign
+{
+ template <typename T>
+ static inline void apply(T values[], T const& value)
+ {
+ values[Index] = value;
+ }
+};
+
+// Specialization avoiding assigning element [2] for only 2 dimensions
+template <> struct array_assign<2, 2>
+{
+ template <typename T> static inline void apply(T [], T const& ) {}
+};
+
+// Specialization avoiding assigning elements for (rarely used) points in 1 dim
+template <> struct array_assign<1, 1>
+{
+ template <typename T> static inline void apply(T [], T const& ) {}
+};
+
+template <> struct array_assign<1, 2>
+{
+ template <typename T> static inline void apply(T [], T const& ) {}
+};
+
+}
/*!
\brief Basic point class, having coordinates defined in a neutral way
\details Defines a neutral point class, fulfilling the Point Concept.
@@ -64,18 +107,77 @@ template
>
class point
{
+ BOOST_MPL_ASSERT_MSG((DimensionCount >= 1),
+ DIMENSION_GREATER_THAN_ZERO_EXPECTED,
+ (boost::mpl::int_<DimensionCount>));
+
+ // The following enum is used to fully instantiate the
+ // CoordinateSystem class and check the correctness of the units
+ // passed for non-Cartesian coordinate systems.
+ enum { cs_check = sizeof(CoordinateSystem) };
+
public:
- /// @brief Default constructor, no initialization
+#if !defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ /// \constructor_default_no_init
+ point() = default;
+#else
+ /// \constructor_default_no_init
inline point()
{}
+#endif
+#else // defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ point()
+ {
+ m_created = 1;
+ std::fill_n(m_values_initialized, DimensionCount, 0);
+ }
+ ~point()
+ {
+ m_created = 0;
+ std::fill_n(m_values_initialized, DimensionCount, 0);
+ }
+#endif
+
+ /// @brief Constructor to set one value
+ explicit inline point(CoordinateType const& v0)
+ {
+ detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
+ detail::array_assign<DimensionCount, 1>::apply(m_values, CoordinateType());
+ detail::array_assign<DimensionCount, 2>::apply(m_values, CoordinateType());
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ m_created = 1;
+ std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
+#endif
+ }
- /// @brief Constructor to set one, two or three values
- explicit inline point(CoordinateType const& v0, CoordinateType const& v1 = 0, CoordinateType const& v2 = 0)
+ /// @brief Constructor to set two values
+ inline point(CoordinateType const& v0, CoordinateType const& v1)
{
- if (DimensionCount >= 1) m_values[0] = v0;
- if (DimensionCount >= 2) m_values[1] = v1;
- if (DimensionCount >= 3) m_values[2] = v2;
+ detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
+ detail::array_assign<DimensionCount, 1>::apply(m_values, v1);
+ detail::array_assign<DimensionCount, 2>::apply(m_values, CoordinateType());
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ m_created = 1;
+ std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
+#endif
+ }
+
+ /// @brief Constructor to set three values
+ inline point(CoordinateType const& v0, CoordinateType const& v1,
+ CoordinateType const& v2)
+ {
+ detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
+ detail::array_assign<DimensionCount, 1>::apply(m_values, v1);
+ detail::array_assign<DimensionCount, 2>::apply(m_values, v2);
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ m_created = 1;
+ std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
+#endif
}
/// @brief Get a coordinate
@@ -84,6 +186,10 @@ public:
template <std::size_t K>
inline CoordinateType const& get() const
{
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+ BOOST_GEOMETRY_ASSERT(m_values_initialized[K] == 1);
+#endif
BOOST_STATIC_ASSERT(K < DimensionCount);
return m_values[K];
}
@@ -94,6 +200,10 @@ public:
template <std::size_t K>
inline void set(CoordinateType const& value)
{
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ BOOST_GEOMETRY_ASSERT(m_created == 1);
+ m_values_initialized[K] = 1;
+#endif
BOOST_STATIC_ASSERT(K < DimensionCount);
m_values[K] = value;
}
@@ -101,6 +211,11 @@ public:
private:
CoordinateType m_values[DimensionCount];
+
+#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
+ int m_created;
+ int m_values_initialized[DimensionCount];
+#endif
};
diff --git a/3party/boost/boost/geometry/geometries/point_xy.hpp b/3party/boost/boost/geometry/geometries/point_xy.hpp
index 652930666f..bbc35d5cec 100644
--- a/3party/boost/boost/geometry/geometries/point_xy.hpp
+++ b/3party/boost/boost/geometry/geometries/point_xy.hpp
@@ -16,6 +16,7 @@
#include <cstddef>
+#include <boost/config.hpp>
#include <boost/mpl/int.hpp>
#include <boost/geometry/core/cs.hpp>
@@ -32,6 +33,7 @@ namespace model { namespace d2
\tparam CoordinateType numeric type, for example, double, float, int
\tparam CoordinateSystem coordinate system, defaults to cs::cartesian
+\qbk{[include reference/geometries/point_xy.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_point Point Concept]
@@ -45,10 +47,14 @@ class point_xy : public model::point<CoordinateType, 2, CoordinateSystem>
{
public:
- /// Default constructor, does not initialize anything
+#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
+ /// \constructor_default_no_init
+ point_xy() = default;
+#else
+ /// \constructor_default_no_init
inline point_xy()
- : model::point<CoordinateType, 2, CoordinateSystem>()
{}
+#endif
/// Constructor with x/y values
inline point_xy(CoordinateType const& x, CoordinateType const& y)
diff --git a/3party/boost/boost/geometry/geometries/pointing_segment.hpp b/3party/boost/boost/geometry/geometries/pointing_segment.hpp
new file mode 100644
index 0000000000..2c4284d10a
--- /dev/null
+++ b/3party/boost/boost/geometry/geometries/pointing_segment.hpp
@@ -0,0 +1,142 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_POINTING_SEGMENT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_POINTING_SEGMENT_HPP
+
+#include <cstddef>
+
+#include <boost/concept/assert.hpp>
+#include <boost/core/addressof.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_const.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+// const or non-const segment type that is meant to be
+// * default constructible
+// * copy constructible
+// * assignable
+// referring_segment does not fit these requirements, hence the
+// pointing_segment class
+//
+// this class is used by the segment_iterator as its value type
+template <typename ConstOrNonConstPoint>
+class pointing_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 pointing_segment()
+ : first(NULL)
+ , second(NULL)
+ {}
+
+ inline pointing_segment(point_type const& p1, point_type const& p2)
+ : first(boost::addressof(p1))
+ , second(boost::addressof(p2))
+ {}
+};
+
+
+} // namespace model
+
+
+// Traits specializations for segment above
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename Point>
+struct tag<model::pointing_segment<Point> >
+{
+ typedef segment_tag type;
+};
+
+template <typename Point>
+struct point_type<model::pointing_segment<Point> >
+{
+ typedef Point type;
+};
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<model::pointing_segment<Point>, 0, Dimension>
+{
+ typedef model::pointing_segment<Point> segment_type;
+ typedef typename geometry::coordinate_type
+ <
+ segment_type
+ >::type coordinate_type;
+
+ static inline coordinate_type get(segment_type const& s)
+ {
+ BOOST_GEOMETRY_ASSERT( s.first != NULL );
+ return geometry::get<Dimension>(*s.first);
+ }
+
+ static inline void set(segment_type& s, coordinate_type const& value)
+ {
+ BOOST_GEOMETRY_ASSERT( s.first != NULL );
+ geometry::set<Dimension>(*s.first, value);
+ }
+};
+
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<model::pointing_segment<Point>, 1, Dimension>
+{
+ typedef model::pointing_segment<Point> segment_type;
+ typedef typename geometry::coordinate_type
+ <
+ segment_type
+ >::type coordinate_type;
+
+ static inline coordinate_type get(segment_type const& s)
+ {
+ BOOST_GEOMETRY_ASSERT( s.second != NULL );
+ return geometry::get<Dimension>(*s.second);
+ }
+
+ static inline void set(segment_type& s, coordinate_type const& value)
+ {
+ BOOST_GEOMETRY_ASSERT( s.second != NULL );
+ geometry::set<Dimension>(*s.second, value);
+ }
+};
+
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_POINTING_SEGMENT_HPP
diff --git a/3party/boost/boost/geometry/geometries/polygon.hpp b/3party/boost/boost/geometry/geometries/polygon.hpp
index ec8d1ec38f..5e6064e893 100644
--- a/3party/boost/boost/geometry/geometries/polygon.hpp
+++ b/3party/boost/boost/geometry/geometries/polygon.hpp
@@ -3,6 +3,7 @@
// 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.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -26,6 +27,11 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/geometries/ring.hpp>
+#include <boost/config.hpp>
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#include <initializer_list>
+#endif
+
namespace boost { namespace geometry
{
@@ -49,6 +55,7 @@ namespace model
\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{[include reference/geometries/polygon.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_polygon Polygon Concept]
@@ -83,6 +90,47 @@ public:
inline ring_type& outer() { return m_outer; }
inline inner_container_type & inners() { return m_inners; }
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+
+ // default constructor definition is required only
+ // if the constructor taking std::initializer_list is defined
+
+ /// \constructor_default{polygon}
+ inline polygon()
+ : m_outer()
+ , m_inners()
+ {}
+
+ /// \constructor_initializer_list{polygon}
+ inline polygon(std::initializer_list<ring_type> l)
+ : m_outer(l.size() > 0 ? *l.begin() : ring_type())
+ , m_inners(l.size() > 0 ? l.begin() + 1 : l.begin(), l.end())
+ {}
+
+// Commented out for now in order to support Boost.Assign
+// Without this assignment operator first the object should be created
+// from initializer list, then it shoudl be moved.
+//// Without this workaround in MSVC the assignment operator is ambiguous
+//#ifndef BOOST_MSVC
+// /// \assignment_initializer_list{polygon}
+// inline polygon & operator=(std::initializer_list<ring_type> l)
+// {
+// if ( l.size() > 0 )
+// {
+// m_outer = *l.begin();
+// m_inners.assign(l.begin() + 1, l.end());
+// }
+// else
+// {
+// m_outer.clear();
+// m_inners.clear();
+// }
+// return *this;
+// }
+//#endif
+
+#endif
+
/// Utility method, clears outer and inner rings
inline void clear()
{
diff --git a/3party/boost/boost/geometry/geometries/ring.hpp b/3party/boost/boost/geometry/geometries/ring.hpp
index 998619785a..01bcf58cf5 100644
--- a/3party/boost/boost/geometry/geometries/ring.hpp
+++ b/3party/boost/boost/geometry/geometries/ring.hpp
@@ -3,6 +3,7 @@
// 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.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -26,6 +27,10 @@
#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/config.hpp>
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#include <initializer_list>
+#endif
namespace boost { namespace geometry
{
@@ -43,6 +48,7 @@ namespace model
\tparam Container container type, for example std::vector, std::deque
\tparam Allocator container-allocator-type
+\qbk{[include reference/geometries/ring.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_ring Ring Concept]
@@ -72,6 +78,28 @@ public :
inline ring(Iterator begin, Iterator end)
: base_type(begin, end)
{}
+
+#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+
+ /// \constructor_initializer_list{ring}
+ inline ring(std::initializer_list<Point> l)
+ : base_type(l.begin(), l.end())
+ {}
+
+// Commented out for now in order to support Boost.Assign
+// Without this assignment operator first the object should be created
+// from initializer list, then it shoudl be moved.
+//// Without this workaround in MSVC the assignment operator is ambiguous
+//#ifndef BOOST_MSVC
+// /// \assignment_initializer_list{ring}
+// inline ring & operator=(std::initializer_list<Point> l)
+// {
+// base_type::assign(l.begin(), l.end());
+// return *this;
+// }
+//#endif
+
+#endif
};
} // namespace model
diff --git a/3party/boost/boost/geometry/geometries/segment.hpp b/3party/boost/boost/geometry/geometries/segment.hpp
index 3f47f79ec4..af406aa09f 100644
--- a/3party/boost/boost/geometry/geometries/segment.hpp
+++ b/3party/boost/boost/geometry/geometries/segment.hpp
@@ -35,14 +35,32 @@ namespace model
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
+
+\qbk{[include reference/geometries/segment.qbk]}
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_segment Segment Concept]
+}
*/
template<typename Point>
class segment : public std::pair<Point, Point>
{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
public :
+
+#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
+ /// \constructor_default_no_init
+ segment() = default;
+#else
+ /// \constructor_default_no_init
inline segment()
{}
+#endif
+ /*!
+ \brief Constructor taking the first and the second point
+ */
inline segment(Point const& p1, Point const& p2)
{
this->first = p1;
@@ -83,6 +101,9 @@ public:
point_type& first;
point_type& second;
+ /*!
+ \brief Constructor taking the first and the second point
+ */
inline referring_segment(point_type& p1, point_type& p2)
: first(p1)
, second(p2)
diff --git a/3party/boost/boost/geometry/geometries/variant.hpp b/3party/boost/boost/geometry/geometries/variant.hpp
index 9db11d5a82..881eab9c8b 100644
--- a/3party/boost/boost/geometry/geometries/variant.hpp
+++ b/3party/boost/boost/geometry/geometries/variant.hpp
@@ -16,6 +16,7 @@
#include <boost/variant/variant_fwd.hpp>
+#include <boost/mpl/front.hpp>
namespace boost { namespace geometry {
@@ -23,7 +24,11 @@ namespace boost { namespace geometry {
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct point_type<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
- : point_type<T0>
+ : point_type<
+ typename boost::mpl::front<
+ typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
+ >::type
+ >
{};
diff --git a/3party/boost/boost/geometry/geometry.hpp b/3party/boost/boost/geometry/geometry.hpp
index 35fb9b80f3..d96facb340 100644
--- a/3party/boost/boost/geometry/geometry.hpp
+++ b/3party/boost/boost/geometry/geometry.hpp
@@ -1,8 +1,14 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -25,6 +31,7 @@
#include <boost/geometry/core/point_order.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/srs.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -34,9 +41,9 @@
#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/radius.hpp>
#include <boost/geometry/core/topological_dimension.hpp>
-
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/arithmetic/dot_product.hpp>
@@ -63,6 +70,7 @@
#include <boost/geometry/algorithms/for_each.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/is_simple.hpp>
#include <boost/geometry/algorithms/is_valid.hpp>
#include <boost/geometry/algorithms/length.hpp>
@@ -70,8 +78,11 @@
#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/num_segments.hpp>
#include <boost/geometry/algorithms/overlaps.hpp>
#include <boost/geometry/algorithms/perimeter.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/relation.hpp>
#include <boost/geometry/algorithms/remove_spikes.hpp>
#include <boost/geometry/algorithms/reverse.hpp>
#include <boost/geometry/algorithms/simplify.hpp>
@@ -82,10 +93,6 @@
#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>
diff --git a/3party/boost/boost/geometry/index/detail/algorithms/content.hpp b/3party/boost/boost/geometry/index/detail/algorithms/content.hpp
index 1c4739d8ef..028113e0ef 100644
--- a/3party/boost/boost/geometry/index/detail/algorithms/content.hpp
+++ b/3party/boost/boost/geometry/index/detail/algorithms/content.hpp
@@ -2,7 +2,7 @@
//
// n-dimensional content (hypervolume) - 2d area, 3d volume, ...
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -24,11 +24,11 @@ struct default_content_result
namespace dispatch {
-template <typename Box, size_t CurrentDimension>
+template <typename Box,
+ std::size_t CurrentDimension = dimension<Box>::value>
struct content_box
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
- //BOOST_STATIC_ASSERT(CurrentDimension <= traits::dimension<Box>::value);
static inline typename detail::default_content_result<Box>::type apply(Box const& b)
{
@@ -66,7 +66,7 @@ struct content<Indexable, box_tag>
{
static typename default_content_result<Indexable>::type apply(Indexable const& b)
{
- return dispatch::content_box<Indexable, dimension<Indexable>::value>::apply(b);
+ return dispatch::content_box<Indexable>::apply(b);
}
};
@@ -75,9 +75,11 @@ struct content<Indexable, box_tag>
template <typename Indexable>
typename default_content_result<Indexable>::type content(Indexable const& b)
{
- return dispatch::content<Indexable,
- typename tag<Indexable>::type
- >::apply(b);
+ return dispatch::content
+ <
+ Indexable,
+ typename tag<Indexable>::type
+ >::apply(b);
}
}}}} // namespace boost::geometry::index::detail
diff --git a/3party/boost/boost/geometry/index/detail/algorithms/intersection_content.hpp b/3party/boost/boost/geometry/index/detail/algorithms/intersection_content.hpp
index 8e3db45305..4afb40479c 100644
--- a/3party/boost/boost/geometry/index/detail/algorithms/intersection_content.hpp
+++ b/3party/boost/boost/geometry/index/detail/algorithms/intersection_content.hpp
@@ -26,8 +26,8 @@ inline typename default_content_result<Box>::type intersection_content(Box const
if ( geometry::intersects(box1, box2) )
{
Box box_intersection;
- geometry::intersection(box1, box2, box_intersection);
- return detail::content(box_intersection);
+ if ( geometry::intersection(box1, box2, box_intersection) )
+ return detail::content(box_intersection);
}
return 0;
}
diff --git a/3party/boost/boost/geometry/index/detail/algorithms/is_valid.hpp b/3party/boost/boost/geometry/index/detail/algorithms/is_valid.hpp
index ee42e39364..676eec2d2a 100644
--- a/3party/boost/boost/geometry/index/detail/algorithms/is_valid.hpp
+++ b/3party/boost/boost/geometry/index/detail/algorithms/is_valid.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
-// n-dimensional box's / point validity check
+// n-dimensional Indexable validity check
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
@@ -11,18 +11,17 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
+#include <cstddef>
+#include <boost/geometry/core/access.hpp>
+
namespace boost { namespace geometry { namespace index { namespace detail {
namespace dispatch {
-template <typename Box, size_t Dimension>
+template <typename Box,
+ std::size_t Dimension = geometry::dimension<Box>::value>
struct is_valid_box
{
- BOOST_MPL_ASSERT_MSG(
- (0 < Dimension && Dimension <= dimension<Box>::value),
- INVALID_DIMENSION_PARAMETER,
- (is_valid_box));
-
static inline bool apply(Box const& b)
{
return is_valid_box<Box, Dimension - 1>::apply(b) &&
@@ -39,7 +38,8 @@ struct is_valid_box<Box, 1>
}
};
-template <typename Indexable, typename Tag>
+template <typename Indexable,
+ typename Tag = typename geometry::tag<Indexable>::type>
struct is_valid
{
BOOST_MPL_ASSERT_MSG(
@@ -62,7 +62,7 @@ struct is_valid<Indexable, box_tag>
{
static inline bool apply(Indexable const& b)
{
- return dispatch::is_valid_box<Indexable, dimension<Indexable>::value>::apply(b);
+ return dispatch::is_valid_box<Indexable>::apply(b);
}
};
@@ -80,7 +80,10 @@ struct is_valid<Indexable, segment_tag>
template <typename Indexable>
inline bool is_valid(Indexable const& b)
{
- return dispatch::is_valid<Indexable, typename tag<Indexable>::type>::apply(b);
+ // CONSIDER: detection of NaNs
+ // e.g. by comparison of b with copy of b
+
+ return dispatch::is_valid<Indexable>::apply(b);
}
}}}} // namespace boost::geometry::index::detail
diff --git a/3party/boost/boost/geometry/index/detail/algorithms/margin.hpp b/3party/boost/boost/geometry/index/detail/algorithms/margin.hpp
index 8e2685ab32..d4876600ac 100644
--- a/3party/boost/boost/geometry/index/detail/algorithms/margin.hpp
+++ b/3party/boost/boost/geometry/index/detail/algorithms/margin.hpp
@@ -2,7 +2,7 @@
//
// n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc...
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -25,7 +25,9 @@ struct default_margin_result
>::type type;
};
-//template <typename Box, size_t CurrentDimension, size_t EdgeDimension>
+//template <typename Box,
+// std::size_t CurrentDimension,
+// std::size_t EdgeDimension = dimension<Box>::value>
//struct margin_for_each_edge
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
@@ -38,7 +40,7 @@ struct default_margin_result
// }
//};
//
-//template <typename Box, size_t CurrentDimension>
+//template <typename Box, std::size_t CurrentDimension>
//struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
@@ -49,7 +51,7 @@ struct default_margin_result
// }
//};
//
-//template <typename Box, size_t CurrentDimension>
+//template <typename Box, std::size_t CurrentDimension>
//struct margin_for_each_edge<Box, CurrentDimension, 1>
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
@@ -69,16 +71,16 @@ struct default_margin_result
// }
//};
//
-//template <typename Box, size_t CurrentDimension>
+//template <typename Box,
+// std::size_t CurrentDimension = dimension<Box>::value>
//struct margin_for_each_dimension
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
-// BOOST_STATIC_ASSERT(CurrentDimension <= detail::traits::dimension<Box>::value);
//
// static inline typename default_margin_result<Box>::type apply(Box const& b)
// {
// return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
-// margin_for_each_edge<Box, CurrentDimension, detail::traits::dimension<Box>::value>::apply(b);
+// margin_for_each_edge<Box, CurrentDimension>::apply(b);
// }
//};
//
@@ -87,7 +89,7 @@ struct default_margin_result
//{
// static inline typename default_margin_result<Box>::type apply(Box const& b)
// {
-// return margin_for_each_edge<Box, 1, detail::traits::dimension<Box>::value>::apply(b);
+// return margin_for_each_edge<Box, 1>::apply(b);
// }
//};
@@ -95,11 +97,11 @@ struct default_margin_result
// Now it's sum of edges lengths
// maybe margin_for_each_dimension should be used to get more or less hypersurface?
-template <typename Box, size_t CurrentDimension>
+template <typename Box,
+ std::size_t CurrentDimension = dimension<Box>::value>
struct simple_margin_for_each_dimension
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
- //BOOST_STATIC_ASSERT(CurrentDimension <= dimension<Box>::value);
static inline typename default_margin_result<Box>::type apply(Box const& b)
{
@@ -140,8 +142,8 @@ struct comparable_margin<Box, box_tag>
static inline result_type apply(Box const& g)
{
- //return detail::margin_for_each_dimension<Box, dimension<Box>::value>::apply(g);
- return detail::simple_margin_for_each_dimension<Box, dimension<Box>::value>::apply(g);
+ //return detail::margin_for_each_dimension<Box>::apply(g);
+ return detail::simple_margin_for_each_dimension<Box>::apply(g);
}
};
@@ -159,7 +161,7 @@ typename default_margin_result<Geometry>::type comparable_margin(Geometry const&
//template <typename Box>
//typename default_margin_result<Box>::type margin(Box const& b)
//{
-// return 2 * detail::margin_for_each_dimension<Box, dimension<Box>::value>::apply(b);
+// return 2 * detail::margin_for_each_dimension<Box>::apply(b);
//}
}}}} // namespace boost::geometry::index::detail
diff --git a/3party/boost/boost/geometry/index/detail/assert.hpp b/3party/boost/boost/geometry/index/detail/assert.hpp
index 22af315bc8..08889df478 100644
--- a/3party/boost/boost/geometry/index/detail/assert.hpp
+++ b/3party/boost/boost/geometry/index/detail/assert.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,22 +9,11 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ASSERT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ASSERT_HPP
-#include <boost/assert.hpp>
+#include <boost/geometry/core/assert.hpp>
-#define BOOST_GEOMETRY_INDEX_ASSERT(CONDITION, TEXT_MSG) \
- BOOST_ASSERT_MSG(CONDITION, TEXT_MSG)
-
-// TODO - change it to something like:
-// BOOST_ASSERT((CONDITION) && (TEXT_MSG))
-
-#if defined(BOOST_DISABLE_ASSERTS) || defined(NDEBUG)
-
-#define BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(PARAM)
+#undef BOOST_GEOMETRY_INDEX_ASSERT
-#else
-
-#define BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(PARAM) PARAM
-
-#endif
+#define BOOST_GEOMETRY_INDEX_ASSERT(CONDITION, TEXT_MSG) \
+ BOOST_GEOMETRY_ASSERT_MSG(CONDITION, TEXT_MSG)
#endif // BOOST_GEOMETRY_INDEX_DETAIL_ASSERT_HPP
diff --git a/3party/boost/boost/geometry/index/detail/bounded_view.hpp b/3party/boost/boost/geometry/index/detail/bounded_view.hpp
index 572368e273..0cd882fc94 100644
--- a/3party/boost/boost/geometry/index/detail/bounded_view.hpp
+++ b/3party/boost/boost/geometry/index/detail/bounded_view.hpp
@@ -155,7 +155,7 @@ struct indexed_access<index::detail::bounded_view<Segment, Box, Tag, box_tag>,
//static inline void set(box_type & b, coordinate_type const& value)
//{
- // BOOST_ASSERT(false);
+ // BOOST_GEOMETRY_INDEX_ASSERT(false, "unable to modify a box through view");
//}
};
@@ -173,7 +173,7 @@ struct indexed_access<index::detail::bounded_view<Segment, Box, Tag, box_tag>,
//static inline void set(box_type & b, coordinate_type const& value)
//{
- // BOOST_ASSERT(false);
+ // BOOST_GEOMETRY_INDEX_ASSERT(false, "unable to modify a box through view");
//}
};
diff --git a/3party/boost/boost/geometry/index/detail/distance_predicates.hpp b/3party/boost/boost/geometry/index/detail/distance_predicates.hpp
index 3e057290a6..9a9371df95 100644
--- a/3party/boost/boost/geometry/index/detail/distance_predicates.hpp
+++ b/3party/boost/boost/geometry/index/detail/distance_predicates.hpp
@@ -3,7 +3,7 @@
// Spatial index distance predicates, calculators and checkers
// used in nearest query - specialized for envelopes
//
-// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -104,13 +104,13 @@ struct calculate_distance
// this handles nearest() with default Point parameter, to_nearest() and bounds
template <typename PointRelation, typename Indexable, typename Tag>
-struct calculate_distance< nearest<PointRelation>, Indexable, Tag >
+struct calculate_distance< predicates::nearest<PointRelation>, Indexable, Tag >
{
typedef detail::relation<PointRelation> relation;
typedef typename relation::value_type point_type;
typedef typename geometry::default_comparable_distance_result<point_type, Indexable>::type result_type;
- static inline bool apply(nearest<PointRelation> const& p, Indexable const& i, result_type & result)
+ static inline bool apply(predicates::nearest<PointRelation> const& p, Indexable const& i, result_type & result)
{
result = geometry::comparable_distance(relation::value(p.point_or_relation), i);
return true;
@@ -118,12 +118,12 @@ struct calculate_distance< nearest<PointRelation>, Indexable, Tag >
};
template <typename Point, typename Indexable>
-struct calculate_distance< nearest< to_centroid<Point> >, Indexable, value_tag>
+struct calculate_distance< predicates::nearest< to_centroid<Point> >, Indexable, value_tag>
{
typedef Point point_type;
typedef typename geometry::default_comparable_distance_result<point_type, Indexable>::type result_type;
- static inline bool apply(nearest< to_centroid<Point> > const& p, Indexable const& i, result_type & result)
+ static inline bool apply(predicates::nearest< to_centroid<Point> > const& p, Indexable const& i, result_type & result)
{
result = index::detail::comparable_distance_centroid(p.point_or_relation.value, i);
return true;
@@ -131,12 +131,12 @@ struct calculate_distance< nearest< to_centroid<Point> >, Indexable, value_tag>
};
template <typename Point, typename Indexable>
-struct calculate_distance< nearest< to_furthest<Point> >, Indexable, value_tag>
+struct calculate_distance< predicates::nearest< to_furthest<Point> >, Indexable, value_tag>
{
typedef Point point_type;
typedef typename geometry::default_comparable_distance_result<point_type, Indexable>::type result_type;
- static inline bool apply(nearest< to_furthest<Point> > const& p, Indexable const& i, result_type & result)
+ static inline bool apply(predicates::nearest< to_furthest<Point> > const& p, Indexable const& i, result_type & result)
{
result = index::detail::comparable_distance_far(p.point_or_relation.value, i);
return true;
@@ -144,13 +144,13 @@ struct calculate_distance< nearest< to_furthest<Point> >, Indexable, value_tag>
};
template <typename SegmentOrLinestring, typename Indexable, typename Tag>
-struct calculate_distance< path<SegmentOrLinestring>, Indexable, Tag>
+struct calculate_distance< predicates::path<SegmentOrLinestring>, Indexable, Tag>
{
typedef typename index::detail::default_path_intersection_distance_type<
Indexable, SegmentOrLinestring
>::type result_type;
- static inline bool apply(path<SegmentOrLinestring> const& p, Indexable const& i, result_type & result)
+ static inline bool apply(predicates::path<SegmentOrLinestring> const& p, Indexable const& i, result_type & result)
{
return index::detail::path_intersection(i, p.geometry, result);
}
diff --git a/3party/boost/boost/geometry/index/detail/exception.hpp b/3party/boost/boost/geometry/index/detail/exception.hpp
index c3ea0e1923..e2090533e7 100644
--- a/3party/boost/boost/geometry/index/detail/exception.hpp
+++ b/3party/boost/boost/geometry/index/detail/exception.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,10 +9,14 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_EXCEPTION_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_EXCEPTION_HPP
+#include <boost/core/no_exceptions_support.hpp>
+
#ifndef BOOST_NO_EXCEPTIONS
#include <stdexcept>
+#include <boost/throw_exception.hpp>
#else
#include <cstdlib>
+#include <boost/geometry/index/detail/assert.hpp>
#endif
namespace boost { namespace geometry { namespace index { namespace detail {
@@ -21,47 +25,58 @@ namespace boost { namespace geometry { namespace index { namespace detail {
inline void throw_runtime_error(const char * str)
{
- throw std::runtime_error(str);
+ BOOST_THROW_EXCEPTION(std::runtime_error(str));
}
inline void throw_logic_error(const char * str)
{
- throw std::logic_error(str);
+ BOOST_THROW_EXCEPTION(std::logic_error(str));
}
inline void throw_invalid_argument(const char * str)
{
- throw std::invalid_argument(str);
+ BOOST_THROW_EXCEPTION(std::invalid_argument(str));
}
inline void throw_length_error(const char * str)
{
- throw std::length_error(str);
+ BOOST_THROW_EXCEPTION(std::length_error(str));
+}
+
+inline void throw_out_of_range(const char * str)
+{
+ BOOST_THROW_EXCEPTION(std::out_of_range(str));
}
#else
inline void throw_runtime_error(const char * str)
{
- BOOST_ASSERT_MSG(!"runtime_error thrown", str);
+ BOOST_GEOMETRY_INDEX_ASSERT(!"runtime_error thrown", str);
std::abort();
}
inline void throw_logic_error(const char * str)
{
- BOOST_ASSERT_MSG(!"logic_error thrown", str);
+ BOOST_GEOMETRY_INDEX_ASSERT(!"logic_error thrown", str);
std::abort();
}
inline void throw_invalid_argument(const char * str)
{
- BOOST_ASSERT_MSG(!"invalid_argument thrown", str);
+ BOOST_GEOMETRY_INDEX_ASSERT(!"invalid_argument thrown", str);
std::abort();
}
inline void throw_length_error(const char * str)
{
- BOOST_ASSERT_MSG(!"length_error thrown", str);
+ BOOST_GEOMETRY_INDEX_ASSERT(!"length_error thrown", str);
+ std::abort();
+}
+
+inline void throw_out_of_range(const char * str)
+{
+ BOOST_GEOMETRY_INDEX_ASSERT(!"out_of_range thrown", str);
std::abort();
}
diff --git a/3party/boost/boost/geometry/index/detail/predicates.hpp b/3party/boost/boost/geometry/index/detail/predicates.hpp
index fd5a927968..01afd16ba6 100644
--- a/3party/boost/boost/geometry/index/detail/predicates.hpp
+++ b/3party/boost/boost/geometry/index/detail/predicates.hpp
@@ -2,7 +2,7 @@
//
// Spatial query predicates definition and checks.
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -16,6 +16,8 @@
namespace boost { namespace geometry { namespace index { namespace detail {
+namespace predicates {
+
// ------------------------------------------------------------------ //
// predicates
// ------------------------------------------------------------------ //
@@ -23,6 +25,7 @@ namespace boost { namespace geometry { namespace index { namespace detail {
template <typename Fun, bool IsFunction>
struct satisfies_impl
{
+ satisfies_impl() : fun(NULL) {}
satisfies_impl(Fun f) : fun(f) {}
Fun * fun;
};
@@ -30,6 +33,7 @@ struct satisfies_impl
template <typename Fun>
struct satisfies_impl<Fun, false>
{
+ satisfies_impl() {}
satisfies_impl(Fun const& f) : fun(f) {}
Fun fun;
};
@@ -40,6 +44,7 @@ struct satisfies
{
typedef satisfies_impl<Fun, ::boost::is_function<Fun>::value> base;
+ satisfies() {}
satisfies(Fun const& f) : base(f) {}
satisfies(base const& b) : base(b) {}
};
@@ -58,22 +63,25 @@ struct within_tag {};
template <typename Geometry, typename Tag, bool Negated>
struct spatial_predicate
{
+ spatial_predicate() {}
spatial_predicate(Geometry const& g) : geometry(g) {}
Geometry geometry;
};
// ------------------------------------------------------------------ //
-// TODO
-// may be replaced by
-// nearest_predicate<Geometry>
-// Geometry geometry
-// unsigned count
-// + point_tag, path_tag
+// CONSIDER: separated nearest<> and path<> may be replaced by
+// nearest_predicate<Geometry, Tag>
+// where Tag = point_tag | path_tag
+// IMPROVEMENT: user-defined nearest predicate allowing to define
+// all or only geometrical aspects of the search
template <typename PointOrRelation>
struct nearest
{
+ nearest()
+// : count(0)
+ {}
nearest(PointOrRelation const& por, unsigned k)
: point_or_relation(por)
, count(k)
@@ -85,6 +93,9 @@ struct nearest
template <typename SegmentOrLinestring>
struct path
{
+ path()
+// : count(0)
+ {}
path(SegmentOrLinestring const& g, unsigned k)
: geometry(g)
, count(k)
@@ -93,6 +104,8 @@ struct path
unsigned count;
};
+} // namespace predicates
+
// ------------------------------------------------------------------ //
// predicate_check
// ------------------------------------------------------------------ //
@@ -109,20 +122,20 @@ struct predicate_check
// ------------------------------------------------------------------ //
template <typename Fun>
-struct predicate_check<satisfies<Fun, false>, value_tag>
+struct predicate_check<predicates::satisfies<Fun, false>, value_tag>
{
template <typename Value, typename Indexable>
- static inline bool apply(satisfies<Fun, false> const& p, Value const& v, Indexable const&)
+ static inline bool apply(predicates::satisfies<Fun, false> const& p, Value const& v, Indexable const&)
{
return p.fun(v);
}
};
template <typename Fun>
-struct predicate_check<satisfies<Fun, true>, value_tag>
+struct predicate_check<predicates::satisfies<Fun, true>, value_tag>
{
template <typename Value, typename Indexable>
- static inline bool apply(satisfies<Fun, true> const& p, Value const& v, Indexable const&)
+ static inline bool apply(predicates::satisfies<Fun, true> const& p, Value const& v, Indexable const&)
{
return !p.fun(v);
}
@@ -137,7 +150,7 @@ struct spatial_predicate_call
};
template <>
-struct spatial_predicate_call<contains_tag>
+struct spatial_predicate_call<predicates::contains_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -147,7 +160,7 @@ struct spatial_predicate_call<contains_tag>
};
template <>
-struct spatial_predicate_call<covered_by_tag>
+struct spatial_predicate_call<predicates::covered_by_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -157,7 +170,7 @@ struct spatial_predicate_call<covered_by_tag>
};
template <>
-struct spatial_predicate_call<covers_tag>
+struct spatial_predicate_call<predicates::covers_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -167,7 +180,7 @@ struct spatial_predicate_call<covers_tag>
};
template <>
-struct spatial_predicate_call<disjoint_tag>
+struct spatial_predicate_call<predicates::disjoint_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -177,7 +190,7 @@ struct spatial_predicate_call<disjoint_tag>
};
template <>
-struct spatial_predicate_call<intersects_tag>
+struct spatial_predicate_call<predicates::intersects_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -187,7 +200,7 @@ struct spatial_predicate_call<intersects_tag>
};
template <>
-struct spatial_predicate_call<overlaps_tag>
+struct spatial_predicate_call<predicates::overlaps_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -197,7 +210,7 @@ struct spatial_predicate_call<overlaps_tag>
};
template <>
-struct spatial_predicate_call<touches_tag>
+struct spatial_predicate_call<predicates::touches_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -207,7 +220,7 @@ struct spatial_predicate_call<touches_tag>
};
template <>
-struct spatial_predicate_call<within_tag>
+struct spatial_predicate_call<predicates::within_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
@@ -220,9 +233,9 @@ struct spatial_predicate_call<within_tag>
// spatial predicate
template <typename Geometry, typename Tag>
-struct predicate_check<spatial_predicate<Geometry, Tag, false>, value_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, value_tag>
{
- typedef spatial_predicate<Geometry, Tag, false> Pred;
+ typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
@@ -233,9 +246,9 @@ struct predicate_check<spatial_predicate<Geometry, Tag, false>, value_tag>
// negated spatial predicate
template <typename Geometry, typename Tag>
-struct predicate_check<spatial_predicate<Geometry, Tag, true>, value_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value_tag>
{
- typedef spatial_predicate<Geometry, Tag, true> Pred;
+ typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
@@ -247,20 +260,20 @@ struct predicate_check<spatial_predicate<Geometry, Tag, true>, value_tag>
// ------------------------------------------------------------------ //
template <typename DistancePredicates>
-struct predicate_check<nearest<DistancePredicates>, value_tag>
+struct predicate_check<predicates::nearest<DistancePredicates>, value_tag>
{
template <typename Value, typename Box>
- static inline bool apply(nearest<DistancePredicates> const&, Value const&, Box const&)
+ static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&)
{
return true;
}
};
template <typename Linestring>
-struct predicate_check<path<Linestring>, value_tag>
+struct predicate_check<predicates::path<Linestring>, value_tag>
{
template <typename Value, typename Box>
- static inline bool apply(path<Linestring> const&, Value const&, Box const&)
+ static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&)
{
return true;
}
@@ -271,10 +284,10 @@ struct predicate_check<path<Linestring>, value_tag>
// ------------------------------------------------------------------ //
template <typename Fun, bool Negated>
-struct predicate_check<satisfies<Fun, Negated>, bounds_tag>
+struct predicate_check<predicates::satisfies<Fun, Negated>, bounds_tag>
{
template <typename Value, typename Box>
- static bool apply(satisfies<Fun, Negated> const&, Value const&, Box const&)
+ static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&)
{
return true;
}
@@ -296,53 +309,53 @@ struct predicate_check<satisfies<Fun, Negated>, bounds_tag>
// spatial predicate - default
template <typename Geometry, typename Tag>
-struct predicate_check<spatial_predicate<Geometry, Tag, false>, bounds_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, bounds_tag>
{
- typedef spatial_predicate<Geometry, Tag, false> Pred;
+ typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return spatial_predicate_call<intersects_tag>::apply(i, p.geometry);
+ return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
}
};
// spatial predicate - contains
template <typename Geometry>
-struct predicate_check<spatial_predicate<Geometry, contains_tag, false>, bounds_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, false>, bounds_tag>
{
- typedef spatial_predicate<Geometry, contains_tag, false> Pred;
+ typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return spatial_predicate_call<contains_tag>::apply(i, p.geometry);
+ return spatial_predicate_call<predicates::contains_tag>::apply(i, p.geometry);
}
};
// spatial predicate - covers
template <typename Geometry>
-struct predicate_check<spatial_predicate<Geometry, covers_tag, false>, bounds_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, false>, bounds_tag>
{
- typedef spatial_predicate<Geometry, covers_tag, false> Pred;
+ typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return spatial_predicate_call<covers_tag>::apply(i, p.geometry);
+ return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry);
}
};
// spatial predicate - disjoint
template <typename Geometry>
-struct predicate_check<spatial_predicate<Geometry, disjoint_tag, false>, bounds_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false>, bounds_tag>
{
- typedef spatial_predicate<Geometry, disjoint_tag, false> Pred;
+ typedef predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return !spatial_predicate_call<covered_by_tag>::apply(i, p.geometry);
+ return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry);
}
};
@@ -360,9 +373,9 @@ struct predicate_check<spatial_predicate<Geometry, disjoint_tag, false>, bounds_
// negated spatial predicate - default
template <typename Geometry, typename Tag>
-struct predicate_check<spatial_predicate<Geometry, Tag, true>, bounds_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, bounds_tag>
{
- typedef spatial_predicate<Geometry, Tag, true> Pred;
+ typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
@@ -373,9 +386,9 @@ struct predicate_check<spatial_predicate<Geometry, Tag, true>, bounds_tag>
// negated spatial predicate - contains
template <typename Geometry>
-struct predicate_check<spatial_predicate<Geometry, contains_tag, true>, bounds_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, predicates::contains_tag, true>, bounds_tag>
{
- typedef spatial_predicate<Geometry, contains_tag, true> Pred;
+ typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& , Value const&, Indexable const& )
@@ -386,9 +399,9 @@ struct predicate_check<spatial_predicate<Geometry, contains_tag, true>, bounds_t
// negated spatial predicate - covers
template <typename Geometry>
-struct predicate_check<spatial_predicate<Geometry, covers_tag, true>, bounds_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, predicates::covers_tag, true>, bounds_tag>
{
- typedef spatial_predicate<Geometry, covers_tag, true> Pred;
+ typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& , Value const&, Indexable const& )
@@ -399,22 +412,22 @@ struct predicate_check<spatial_predicate<Geometry, covers_tag, true>, bounds_tag
// negated spatial predicate - intersects
template <typename Geometry>
-struct predicate_check<spatial_predicate<Geometry, intersects_tag, true>, bounds_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, predicates::intersects_tag, true>, bounds_tag>
{
- typedef spatial_predicate<Geometry, intersects_tag, true> Pred;
+ typedef predicates::spatial_predicate<Geometry, predicates::intersects_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return !spatial_predicate_call<covered_by_tag>::apply(i, p.geometry);
+ return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry);
}
};
// negated spatial predicate - overlaps
template <typename Geometry>
-struct predicate_check<spatial_predicate<Geometry, overlaps_tag, true>, bounds_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true>, bounds_tag>
{
- typedef spatial_predicate<Geometry, overlaps_tag, true> Pred;
+ typedef predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& , Value const&, Indexable const& )
@@ -425,34 +438,34 @@ struct predicate_check<spatial_predicate<Geometry, overlaps_tag, true>, bounds_t
// negated spatial predicate - touches
template <typename Geometry>
-struct predicate_check<spatial_predicate<Geometry, touches_tag, true>, bounds_tag>
+struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touches_tag, true>, bounds_tag>
{
- typedef spatial_predicate<Geometry, touches_tag, true> Pred;
+ typedef predicates::spatial_predicate<Geometry, predicates::touches_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return !spatial_predicate_call<intersects_tag>::apply(i, p.geometry);
+ return !spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
}
};
// ------------------------------------------------------------------ //
template <typename DistancePredicates>
-struct predicate_check<nearest<DistancePredicates>, bounds_tag>
+struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag>
{
template <typename Value, typename Box>
- static inline bool apply(nearest<DistancePredicates> const&, Value const&, Box const&)
+ static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&)
{
return true;
}
};
template <typename Linestring>
-struct predicate_check<path<Linestring>, bounds_tag>
+struct predicate_check<predicates::path<Linestring>, bounds_tag>
{
template <typename Value, typename Box>
- static inline bool apply(path<Linestring> const&, Value const&, Box const&)
+ static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&)
{
return true;
}
@@ -698,13 +711,13 @@ struct predicates_is_distance
};
template <typename DistancePredicates>
-struct predicates_is_distance< nearest<DistancePredicates> >
+struct predicates_is_distance< predicates::nearest<DistancePredicates> >
{
static const unsigned value = 1;
};
template <typename Linestring>
-struct predicates_is_distance< path<Linestring> >
+struct predicates_is_distance< predicates::path<Linestring> >
{
static const unsigned value = 1;
};
diff --git a/3party/boost/boost/geometry/index/detail/pushable_array.hpp b/3party/boost/boost/geometry/index/detail/pushable_array.hpp
deleted file mode 100644
index 180d46580b..0000000000
--- a/3party/boost/boost/geometry/index/detail/pushable_array.hpp
+++ /dev/null
@@ -1,171 +0,0 @@
-// Boost.Geometry Index
-//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
-//
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_PUSHABLE_ARRAY_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_PUSHABLE_ARRAY_HPP
-
-#include <boost/array.hpp>
-
-#include <boost/geometry/index/detail/assert.hpp>
-
-namespace boost { namespace geometry { namespace index { namespace detail {
-
-template <typename Element, size_t Capacity>
-class pushable_array
-{
- typedef typename boost::array<Element, Capacity> array_type;
-
-public:
- typedef typename array_type::value_type value_type;
- typedef typename array_type::size_type size_type;
- typedef typename array_type::iterator iterator;
- typedef typename array_type::const_iterator const_iterator;
- typedef typename array_type::reverse_iterator reverse_iterator;
- typedef typename array_type::const_reverse_iterator const_reverse_iterator;
- typedef typename array_type::reference reference;
- typedef typename array_type::const_reference const_reference;
-
- inline pushable_array()
- : m_size(0)
- {}
-
- inline explicit pushable_array(size_type s)
- : m_size(s)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(s <= Capacity, "size too big");
- }
-
- inline void resize(size_type s)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(s <= Capacity, "size too big");
- m_size = s;
- }
-
- inline void reserve(size_type /*s*/)
- {
- //BOOST_GEOMETRY_INDEX_ASSERT(s <= Capacity, "size too big");
- // do nothing
- }
-
- inline Element & operator[](size_type i)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(i < m_size, "index of the element outside the container");
- return m_array[i];
- }
-
- inline Element const& operator[](size_type i) const
- {
- BOOST_GEOMETRY_INDEX_ASSERT(i < m_size, "index of the element outside the container");
- return m_array[i];
- }
-
- inline Element const& front() const
- {
- BOOST_GEOMETRY_INDEX_ASSERT(0 < m_size, "there are no elements in the container");
- return m_array.front();
- }
-
- inline Element & front()
- {
- BOOST_GEOMETRY_INDEX_ASSERT(0 < m_size, "there are no elements in the container");
- return m_array.front();
- }
-
- inline Element const& back() const
- {
- BOOST_GEOMETRY_INDEX_ASSERT(0 < m_size, "there are no elements in the container");
- return *(begin() + (m_size - 1));
- }
-
- inline Element & back()
- {
- BOOST_GEOMETRY_INDEX_ASSERT(0 < m_size, "there are no elements in the container");
- return *(begin() + (m_size - 1));
- }
-
- inline iterator begin()
- {
- return m_array.begin();
- }
-
- inline iterator end()
- {
- return m_array.begin() + m_size;
- }
-
- inline const_iterator begin() const
- {
- return m_array.begin();
- }
-
- inline const_iterator end() const
- {
- return m_array.begin() + m_size;
- }
-
- inline reverse_iterator rbegin()
- {
- return reverse_iterator(end());
- }
-
- inline reverse_iterator rend()
- {
- return reverse_iterator(begin());
- }
-
- inline const_reverse_iterator rbegin() const
- {
- return const_reverse_iterator(end());
- }
-
- inline const_reverse_iterator rend() const
- {
- return const_reverse_iterator(begin());
- }
-
- inline void clear()
- {
- m_size = 0;
- }
-
- inline void push_back(Element const& v)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(m_size < Capacity, "can't further increase the size of the container");
- m_array[m_size] = v;
- ++m_size;
- }
-
- inline void pop_back()
- {
- BOOST_GEOMETRY_INDEX_ASSERT(0 < m_size, "there are no elements in the container");
- --m_size;
- }
-
- inline bool empty() const
- {
- return m_size == 0;
- }
-
- inline size_t size() const
- {
- return m_size;
- }
-
- inline size_t capacity() const
- {
- return Capacity;
- }
-
-private:
- boost::array<Element, Capacity> m_array;
- size_type m_size;
-};
-
-}}}} // namespace boost::geometry::index::detail
-
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_PUSHABLE_ARRAY_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/iterators.hpp b/3party/boost/boost/geometry/index/detail/rtree/iterators.hpp
new file mode 100644
index 0000000000..a47dd7ea43
--- /dev/null
+++ b/3party/boost/boost/geometry/index/detail/rtree/iterators.hpp
@@ -0,0 +1,122 @@
+// Boost.Geometry Index
+//
+// R-tree iterators
+//
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
+
+namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
+
+template <typename Value, typename Allocators>
+struct end_iterator
+{
+ typedef std::forward_iterator_tag iterator_category;
+ typedef Value value_type;
+ typedef typename Allocators::const_reference reference;
+ typedef typename Allocators::difference_type difference_type;
+ typedef typename Allocators::const_pointer pointer;
+
+ reference operator*() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
+ pointer p(0);
+ return *p;
+ }
+
+ const value_type * operator->() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
+ const value_type * p = 0;
+ return p;
+ }
+
+ end_iterator & operator++()
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
+ return *this;
+ }
+
+ end_iterator operator++(int)
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
+ return *this;
+ }
+
+ friend bool operator==(end_iterator const& /*l*/, end_iterator const& /*r*/)
+ {
+ return true;
+ }
+};
+
+template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+class iterator
+{
+ typedef visitors::iterator<Value, Options, Translator, Box, Allocators> visitor_type;
+ typedef typename visitor_type::node_pointer node_pointer;
+
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef Value value_type;
+ typedef typename Allocators::const_reference reference;
+ typedef typename Allocators::difference_type difference_type;
+ typedef typename Allocators::const_pointer pointer;
+
+ inline iterator()
+ {}
+
+ inline iterator(node_pointer root)
+ {
+ m_visitor.initialize(root);
+ }
+
+ reference operator*() const
+ {
+ return m_visitor.dereference();
+ }
+
+ const value_type * operator->() const
+ {
+ return boost::addressof(m_visitor.dereference());
+ }
+
+ iterator & operator++()
+ {
+ m_visitor.increment();
+ return *this;
+ }
+
+ iterator operator++(int)
+ {
+ iterator temp = *this;
+ this->operator++();
+ return temp;
+ }
+
+ friend bool operator==(iterator const& l, iterator const& r)
+ {
+ return l.m_visitor == r.m_visitor;
+ }
+
+ friend bool operator==(iterator const& l, end_iterator<Value, Allocators> const& /*r*/)
+ {
+ return l.m_visitor.is_end();
+ }
+
+ friend bool operator==(end_iterator<Value, Allocators> const& /*l*/, iterator const& r)
+ {
+ return r.m_visitor.is_end();
+ }
+
+private:
+ visitor_type m_visitor;
+};
+
+}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp b/3party/boost/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp
index bfe603001f..a10b046c0d 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp
@@ -149,7 +149,7 @@ struct find_greatest_normalized_separation
// highest_low - lowest_high
separation = difference<separation_type>(lowest_high, highest_low);
- // BOOST_ASSERT(0 <= width);
+ // BOOST_GEOMETRY_INDEX_ASSERT(0 <= width);
if ( std::numeric_limits<coordinate_type>::epsilon() < width )
separation /= width;
@@ -222,7 +222,6 @@ struct pick_seeds_impl
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef find_greatest_normalized_separation<
Elements, Parameters, Translator,
@@ -282,27 +281,25 @@ struct pick_seeds_impl<Elements, Parameters, Translator, 1>
// from void linear_pick_seeds(node_pointer const& n, unsigned int &seed1, unsigned int &seed2) const
template <typename Elements, typename Parameters, typename Translator>
-struct pick_seeds
+inline void pick_seeds(Elements const& elements,
+ Parameters const& parameters,
+ Translator const& tr,
+ size_t & seed1,
+ size_t & seed2)
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename coordinate_type<indexable_type>::type coordinate_type;
-
- static const size_t dimension = geometry::dimension<indexable_type>::value;
- typedef pick_seeds_impl<Elements, Parameters, Translator, dimension> impl;
+ typedef pick_seeds_impl
+ <
+ Elements, Parameters, Translator,
+ geometry::dimension<indexable_type>::value
+ > impl;
typedef typename impl::separation_type separation_type;
- static inline void apply(Elements const& elements,
- Parameters const& parameters,
- Translator const& tr,
- size_t & seed1,
- size_t & seed2)
- {
- separation_type separation = 0;
- pick_seeds_impl<Elements, Parameters, Translator, dimension>::apply(elements, parameters, tr, separation, seed1, seed2);
- }
-};
+ separation_type separation = 0;
+ impl::apply(elements, parameters, tr, separation, seed1, seed2);
+}
} // namespace linear
@@ -337,18 +334,16 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
BOOST_GEOMETRY_INDEX_ASSERT(elements1.size() == elements1_count, "unexpected number of elements");
- // copy original elements
- // TODO: use container_from_elements_type for std::allocator
- elements_type elements_copy(elements1); // MAY THROW, STRONG (alloc, copy)
+ // copy original elements - use in-memory storage (std::allocator)
+ // TODO: move if noexcept
+ typedef typename rtree::container_from_elements_type<elements_type, element_type>::type
+ container_type;
+ container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy)
// calculate initial seeds
size_t seed1 = 0;
size_t seed2 = 0;
- linear::pick_seeds<
- elements_type,
- parameters_type,
- Translator
- >::apply(elements_copy, parameters, translator, seed1, seed2);
+ linear::pick_seeds(elements_copy, parameters, translator, seed1, seed2);
// prepare nodes' elements containers
elements1.clear();
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/auto_deallocator.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/auto_deallocator.hpp
deleted file mode 100644
index dd55c6d76c..0000000000
--- a/3party/boost/boost/geometry/index/detail/rtree/node/auto_deallocator.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Boost.Geometry Index
-//
-// R-tree auto deallocator
-//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
-//
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_AUTO_DEALLOCATOR_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_AUTO_DEALLOCATOR_HPP
-
-namespace boost { namespace geometry { namespace index {
-
-namespace detail { namespace rtree {
-
-template <typename Alloc>
-class auto_deallocator
-{
- auto_deallocator(auto_deallocator const&);
- auto_deallocator & operator=(auto_deallocator const&);
-public:
- typedef typename Alloc::pointer pointer;
- inline auto_deallocator(Alloc & a, pointer p) : m_alloc(a), m_ptr(p) {}
- inline ~auto_deallocator() { if ( m_ptr ) boost::container::allocator_traits<Alloc>::deallocate(m_alloc, m_ptr, 1); }
- inline void release() { m_ptr = 0; }
- inline pointer ptr() { return m_ptr; }
-private:
- Alloc & m_alloc;
- pointer m_ptr;
-};
-
-}} // namespace detail::rtree
-
-}}} // namespace boost::geometry::index
-
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_AUTO_DEALLOCATOR_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp
deleted file mode 100644
index 477d937dbb..0000000000
--- a/3party/boost/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// Boost.Geometry Index
-//
-// R-tree nodes dynamic visitor and nodes base type
-//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
-//
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_DYNAMIC_VISITOR_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_DYNAMIC_VISITOR_HPP
-
-namespace boost { namespace geometry { namespace index {
-
-namespace detail { namespace rtree {
-
-// visitor forward declaration
-template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag, bool IsVisitableConst>
-struct dynamic_visitor;
-
-// node
-
-template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
-struct dynamic_node
-{
- virtual ~dynamic_node() {}
- virtual void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, Tag, false> &) = 0;
- virtual void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, Tag, true> &) const = 0;
-};
-
-// nodes variants forward declarations
-
-template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
-struct dynamic_internal_node;
-
-template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
-struct dynamic_leaf;
-
-// visitor
-
-template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
-struct dynamic_visitor<Value, Parameters, Box, Allocators, Tag, true>
-{
- typedef dynamic_internal_node<Value, Parameters, Box, Allocators, Tag> internal_node;
- typedef dynamic_leaf<Value, Parameters, Box, Allocators, Tag> leaf;
-
- virtual ~dynamic_visitor() {}
-
- virtual void operator()(internal_node const&) = 0;
- virtual void operator()(leaf const&) = 0;
-};
-
-template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
-struct dynamic_visitor<Value, Parameters, Box, Allocators, Tag, false>
-{
- typedef dynamic_internal_node<Value, Parameters, Box, Allocators, Tag> internal_node;
- typedef dynamic_leaf<Value, Parameters, Box, Allocators, Tag> leaf;
-
- virtual ~dynamic_visitor() {}
-
- virtual void operator()(internal_node &) = 0;
- virtual void operator()(leaf &) = 0;
-};
-
-// nodes conversion
-
-template <typename Derived, typename Parameters, typename Value, typename Box, typename Allocators, typename Tag>
-inline Derived & get(dynamic_node<Value, Parameters, Box, Allocators, Tag> & n)
-{
- BOOST_GEOMETRY_INDEX_ASSERT(dynamic_cast<Derived*>(&n), "can't cast to a Derived type");
- return static_cast<Derived&>(n);
-}
-
-// apply visitor
-
-template <typename Visitor, typename Visitable>
-inline void apply_visitor(Visitor & v, Visitable & n)
-{
- BOOST_GEOMETRY_INDEX_ASSERT(&n, "null ptr");
- n.apply_visitor(v);
-}
-
-}} // namespace detail::rtree
-
-}}} // namespace boost::geometry::index
-
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_DYNAMIC_VISITOR_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/node.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/node.hpp
index d788cdc0da..528d473170 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/node/node.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/node/node.hpp
@@ -2,7 +2,7 @@
//
// R-tree nodes
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -16,17 +16,18 @@
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
-#include <boost/geometry/index/detail/rtree/node/auto_deallocator.hpp>
+#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
+#include <boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp>
-#include <boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp>
-#include <boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp>
-#include <boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp>
+//#include <boost/geometry/index/detail/rtree/node/weak_visitor.hpp>
+//#include <boost/geometry/index/detail/rtree/node/weak_dynamic.hpp>
+//#include <boost/geometry/index/detail/rtree/node/weak_static.hpp>
-#include <boost/geometry/index/detail/rtree/node/static_visitor.hpp>
-#include <boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp>
-#include <boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp>
+#include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
+#include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
+#include <boost/geometry/index/detail/rtree/node/variant_static.hpp>
-#include <boost/geometry/index/detail/rtree/node/node_auto_ptr.hpp>
+#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/algorithms/expand.hpp>
@@ -69,11 +70,11 @@ struct destroy_element
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
- typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
+ typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
inline static void apply(typename internal_node::elements_type::value_type & element, Allocators & allocators)
{
- node_auto_ptr dummy(element.second, allocators);
+ subtree_destroyer dummy(element.second, allocators);
element.second = 0;
}
@@ -84,39 +85,41 @@ struct destroy_element
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct destroy_elements
{
- typedef typename Options::parameters_type parameters_type;
-
- typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
- typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
-
- typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
-
- inline static void apply(typename internal_node::elements_type & elements, Allocators & allocators)
+ template <typename Range>
+ inline static void apply(Range & elements, Allocators & allocators)
{
- for ( size_t i = 0 ; i < elements.size() ; ++i )
- {
- node_auto_ptr dummy(elements[i].second, allocators);
- elements[i].second = 0;
- }
+ apply(boost::begin(elements), boost::end(elements), allocators);
}
- inline static void apply(typename leaf::elements_type &, Allocators &)
- {}
+ template <typename It>
+ inline static void apply(It first, It last, Allocators & allocators)
+ {
+ typedef boost::mpl::bool_<
+ boost::is_same<
+ Value, typename std::iterator_traits<It>::value_type
+ >::value
+ > is_range_of_values;
- inline static void apply(typename internal_node::elements_type::iterator first,
- typename internal_node::elements_type::iterator last,
- Allocators & allocators)
+ apply_dispatch(first, last, allocators, is_range_of_values());
+ }
+
+private:
+ template <typename It>
+ inline static void apply_dispatch(It first, It last, Allocators & allocators,
+ boost::mpl::bool_<false> const& /*is_range_of_values*/)
{
+ typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
+
for ( ; first != last ; ++first )
{
- node_auto_ptr dummy(first->second, allocators);
+ subtree_destroyer dummy(first->second, allocators);
first->second = 0;
}
}
- inline static void apply(typename leaf::elements_type::iterator /*first*/,
- typename leaf::elements_type::iterator /*last*/,
- Allocators & /*allocators*/)
+ template <typename It>
+ inline static void apply_dispatch(It /*first*/, It /*last*/, Allocators & /*allocators*/,
+ boost::mpl::bool_<true> const& /*is_range_of_values*/)
{}
};
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/node_elements.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/node_elements.hpp
new file mode 100644
index 0000000000..e3bfb701f8
--- /dev/null
+++ b/3party/boost/boost/geometry/index/detail/rtree/node/node_elements.hpp
@@ -0,0 +1,95 @@
+// Boost.Geometry Index
+//
+// R-tree node elements access
+//
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_ELEMENTS_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_ELEMENTS_HPP
+
+#include <boost/container/vector.hpp>
+#include <boost/geometry/index/detail/varray.hpp>
+#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree {
+
+// element's indexable type
+
+template <typename Element, typename Translator>
+struct element_indexable_type
+{
+ typedef typename indexable_type<Translator>::type type;
+};
+
+template <typename First, typename Pointer, typename Translator>
+struct element_indexable_type<
+ rtree::ptr_pair<First, Pointer>,
+ Translator
+>
+{
+ typedef First type;
+};
+
+// element's indexable getter
+
+template <typename Element, typename Translator>
+typename result_type<Translator>::type
+element_indexable(Element const& el, Translator const& tr)
+{
+ return tr(el);
+}
+
+template <typename First, typename Pointer, typename Translator>
+First const&
+element_indexable(rtree::ptr_pair<First, Pointer> const& el, Translator const& /*tr*/)
+{
+ return el.first;
+}
+
+// nodes elements
+
+template <typename Node>
+struct elements_type
+{
+ typedef typename Node::elements_type type;
+};
+
+template <typename Node>
+inline typename elements_type<Node>::type &
+elements(Node & n)
+{
+ return n.elements;
+}
+
+template <typename Node>
+inline typename elements_type<Node>::type const&
+elements(Node const& n)
+{
+ return n.elements;
+}
+
+// elements derived type
+
+template <typename Elements, typename NewValue>
+struct container_from_elements_type
+{
+ typedef boost::container::vector<NewValue> type;
+};
+
+template <typename OldValue, size_t N, typename NewValue>
+struct container_from_elements_type<detail::varray<OldValue, N>, NewValue>
+{
+ typedef detail::varray<NewValue, N> type;
+};
+
+}} // namespace detail::rtree
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_ELEMENTS_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp
new file mode 100644
index 0000000000..2d08d89ef7
--- /dev/null
+++ b/3party/boost/boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp
@@ -0,0 +1,48 @@
+// Boost.Geometry Index
+//
+// R-tree scoped deallocator
+//
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree {
+
+template <typename Alloc>
+class scoped_deallocator
+{
+ scoped_deallocator(scoped_deallocator const&);
+ scoped_deallocator & operator=(scoped_deallocator const&);
+public:
+ typedef typename Alloc::pointer pointer;
+ inline scoped_deallocator(pointer p, Alloc & a)
+ : m_ptr(p), m_alloc(a)
+ {}
+ inline ~scoped_deallocator()
+ {
+ if ( m_ptr )
+ {
+ boost::container::allocator_traits<Alloc>::deallocate(m_alloc, m_ptr, 1);
+ }
+ }
+ inline void release()
+ {
+ m_ptr = 0;
+ }
+private:
+ pointer m_ptr;
+ Alloc & m_alloc;
+};
+
+}} // namespace detail::rtree
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/node_auto_ptr.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp
index c19e123b62..3376068eed 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/node/node_auto_ptr.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp
@@ -1,15 +1,15 @@
// Boost.Geometry Index
//
-// R-tree node auto ptr
+// R-tree subtree scoped destroyer
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_AUTO_PTR_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_AUTO_PTR_HPP
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SUBTREE_DESTROYED_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SUBTREE_DESTROYED_HPP
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
@@ -17,31 +17,29 @@ namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
-// TODO - change the name to node_scoped_ptr
-
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
-class node_auto_ptr
+class subtree_destroyer
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename Allocators::node_pointer pointer;
- node_auto_ptr(node_auto_ptr const&);
- node_auto_ptr & operator=(node_auto_ptr const&);
+ subtree_destroyer(subtree_destroyer const&);
+ subtree_destroyer & operator=(subtree_destroyer const&);
public:
- node_auto_ptr(pointer ptr, Allocators & allocators)
+ subtree_destroyer(pointer ptr, Allocators & allocators)
: m_ptr(ptr)
, m_allocators(allocators)
{}
- ~node_auto_ptr()
+ ~subtree_destroyer()
{
reset();
}
void reset(pointer ptr = 0)
{
- if ( m_ptr )
+ if ( m_ptr && m_ptr != ptr )
{
detail::rtree::visitors::destroy<Value, Options, Translator, Box, Allocators> del_v(m_ptr, m_allocators);
detail::rtree::apply_visitor(del_v, *m_ptr);
@@ -78,4 +76,4 @@ private:
}}} // namespace boost::geometry::index
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_AUTO_PTR_HPP
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SUBTREE_DESTROYED_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp
index 8cf7c9c0d7..8e052e5216 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp
@@ -1,15 +1,15 @@
// Boost.Geometry Index
//
-// R-tree nodes based on Boost.Variant, storing std::vectors
+// R-tree nodes based on Boost.Variant, storing dynamic-size containers
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_VARIANT_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_VARIANT_HPP
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP
namespace boost { namespace geometry { namespace index {
@@ -18,19 +18,19 @@ namespace detail { namespace rtree {
// nodes default types
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
-struct static_internal_node
+struct variant_internal_node
{
- typedef typename Allocators::node_allocator_type::template rebind<
- rtree::ptr_pair<Box, typename Allocators::node_pointer>
- >::other elements_allocator_type;
-
- typedef boost::container::vector<
- rtree::ptr_pair<Box, typename Allocators::node_pointer>,
- elements_allocator_type
- > elements_type;
+ typedef boost::container::vector
+ <
+ rtree::ptr_pair<Box, typename Allocators::node_pointer>,
+ typename Allocators::node_allocator_type::template rebind
+ <
+ rtree::ptr_pair<Box, typename Allocators::node_pointer>
+ >::other
+ > elements_type;
template <typename Al>
- inline static_internal_node(Al const& al)
+ inline variant_internal_node(Al const& al)
: elements(al)
{}
@@ -38,19 +38,19 @@ struct static_internal_node
};
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
-struct static_leaf
+struct variant_leaf
{
- typedef typename Allocators::node_allocator_type::template rebind<
- Value
- >::other elements_allocator_type;
-
- typedef boost::container::vector<
- Value,
- elements_allocator_type
- > elements_type;
+ typedef boost::container::vector
+ <
+ Value,
+ typename Allocators::node_allocator_type::template rebind
+ <
+ Value
+ >::other
+ > elements_type;
template <typename Al>
- inline static_leaf(Al const& al)
+ inline variant_leaf(Al const& al)
: elements(al)
{}
@@ -60,30 +60,30 @@ struct static_leaf
// nodes traits
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct node<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag>
+struct node<Value, Parameters, Box, Allocators, node_variant_dynamic_tag>
{
typedef boost::variant<
- static_leaf<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag>,
- static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag>
+ variant_leaf<Value, Parameters, Box, Allocators, node_variant_dynamic_tag>,
+ variant_internal_node<Value, Parameters, Box, Allocators, node_variant_dynamic_tag>
> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct internal_node<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag>
+struct internal_node<Value, Parameters, Box, Allocators, node_variant_dynamic_tag>
{
- typedef static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag> type;
+ typedef variant_internal_node<Value, Parameters, Box, Allocators, node_variant_dynamic_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct leaf<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag>
+struct leaf<Value, Parameters, Box, Allocators, node_variant_dynamic_tag>
{
- typedef static_leaf<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag> type;
+ typedef variant_leaf<Value, Parameters, Box, Allocators, node_variant_dynamic_tag> type;
};
// visitor traits
template <typename Value, typename Parameters, typename Box, typename Allocators, bool IsVisitableConst>
-struct visitor<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag, IsVisitableConst>
+struct visitor<Value, Parameters, Box, Allocators, node_variant_dynamic_tag, IsVisitableConst>
{
typedef static_visitor<> type;
};
@@ -91,9 +91,13 @@ struct visitor<Value, Parameters, Box, Allocators, node_s_mem_dynamic_tag, IsVis
// allocators
template <typename Allocator, typename Value, typename Parameters, typename Box>
-class allocators<Allocator, Value, Parameters, Box, node_s_mem_dynamic_tag>
+class allocators<Allocator, Value, Parameters, Box, node_variant_dynamic_tag>
: public Allocator::template rebind<
- typename node<Value, Parameters, Box, allocators<Allocator, Value, Parameters, Box, node_s_mem_dynamic_tag>, node_s_mem_dynamic_tag>::type
+ typename node<
+ Value, Parameters, Box,
+ allocators<Allocator, Value, Parameters, Box, node_variant_dynamic_tag>,
+ node_variant_dynamic_tag
+ >::type
>::other
{
typedef typename Allocator::template rebind<
@@ -112,15 +116,11 @@ public:
typedef typename value_allocator_type::const_pointer const_pointer;
typedef typename Allocator::template rebind<
- typename node<Value, Parameters, Box, allocators, node_s_mem_dynamic_tag>::type
+ typename node<Value, Parameters, Box, allocators, node_variant_dynamic_tag>::type
>::other::pointer node_pointer;
-// typedef typename Allocator::template rebind<
-// typename internal_node<Value, Parameters, Box, allocators, node_s_mem_dynamic_tag>::type
-// >::other::pointer internal_node_pointer;
-
typedef typename Allocator::template rebind<
- typename node<Value, Parameters, Box, allocators, node_s_mem_dynamic_tag>::type
+ typename node<Value, Parameters, Box, allocators, node_variant_dynamic_tag>::type
>::other node_allocator_type;
inline allocators()
@@ -168,7 +168,7 @@ public:
// create_node_variant
template <typename VariantPtr, typename Node>
-struct create_static_node
+struct create_variant_node
{
template <typename AllocNode>
static inline VariantPtr apply(AllocNode & alloc_node)
@@ -181,7 +181,7 @@ struct create_static_node
if ( 0 == p )
throw_runtime_error("boost::geometry::index::rtree node creation failed");
- auto_deallocator<AllocNode> deallocator(alloc_node, p);
+ scoped_deallocator<AllocNode> deallocator(p, alloc_node);
Al::construct(alloc_node, boost::addressof(*p), Node(alloc_node)); // implicit cast to Variant
@@ -193,7 +193,7 @@ struct create_static_node
// destroy_node_variant
template <typename Node>
-struct destroy_static_node
+struct destroy_variant_node
{
template <typename AllocNode, typename VariantPtr>
static inline void apply(AllocNode & alloc_node, VariantPtr n)
@@ -210,15 +210,15 @@ struct destroy_static_node
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct create_node<
Allocators,
- static_internal_node<Value, Parameters, Box, Allocators, Tag>
+ variant_internal_node<Value, Parameters, Box, Allocators, Tag>
>
{
static inline typename Allocators::node_pointer
apply(Allocators & allocators)
{
- return create_static_node<
+ return create_variant_node<
typename Allocators::node_pointer,
- static_internal_node<Value, Parameters, Box, Allocators, Tag>
+ variant_internal_node<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.node_allocator());
}
};
@@ -226,15 +226,15 @@ struct create_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct create_node<
Allocators,
- static_leaf<Value, Parameters, Box, Allocators, Tag>
+ variant_leaf<Value, Parameters, Box, Allocators, Tag>
>
{
static inline typename Allocators::node_pointer
apply(Allocators & allocators)
{
- return create_static_node<
+ return create_variant_node<
typename Allocators::node_pointer,
- static_leaf<Value, Parameters, Box, Allocators, Tag>
+ variant_leaf<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.node_allocator());
}
};
@@ -244,13 +244,13 @@ struct create_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct destroy_node<
Allocators,
- static_internal_node<Value, Parameters, Box, Allocators, Tag>
+ variant_internal_node<Value, Parameters, Box, Allocators, Tag>
>
{
static inline void apply(Allocators & allocators, typename Allocators::node_pointer n)
{
- destroy_static_node<
- static_internal_node<Value, Parameters, Box, Allocators, Tag>
+ destroy_variant_node<
+ variant_internal_node<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.node_allocator(), n);
}
};
@@ -258,13 +258,13 @@ struct destroy_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct destroy_node<
Allocators,
- static_leaf<Value, Parameters, Box, Allocators, Tag>
+ variant_leaf<Value, Parameters, Box, Allocators, Tag>
>
{
static inline void apply(Allocators & allocators, typename Allocators::node_pointer n)
{
- destroy_static_node<
- static_leaf<Value, Parameters, Box, Allocators, Tag>
+ destroy_variant_node<
+ variant_leaf<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.node_allocator(), n);
}
};
@@ -273,4 +273,4 @@ struct destroy_node<
}}} // namespace boost::geometry::index
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_VARIANT_HPP
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/variant_static.hpp
index 5df869c954..174ceb7e7f 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/node/variant_static.hpp
@@ -2,14 +2,14 @@
//
// R-tree nodes based on Boost.Variant, storing static-size containers
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_VARIANT_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_VARIANT_HPP
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP
namespace boost { namespace geometry { namespace index {
@@ -18,37 +18,29 @@ namespace detail { namespace rtree {
// nodes default types
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
+struct variant_internal_node<Value, Parameters, Box, Allocators, node_variant_static_tag>
{
- typedef typename Allocators::node_allocator_type::template rebind<
- rtree::ptr_pair<Box, typename Allocators::node_pointer>
- >::other elements_allocator_type;
-
typedef detail::varray<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
- inline static_internal_node(Alloc const&) {}
+ inline variant_internal_node(Alloc const&) {}
elements_type elements;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
+struct variant_leaf<Value, Parameters, Box, Allocators, node_variant_static_tag>
{
- typedef typename Allocators::node_allocator_type::template rebind<
- Value
- >::other elements_allocator_type;
-
typedef detail::varray<
Value,
Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
- inline static_leaf(Alloc const&) {}
+ inline variant_leaf(Alloc const&) {}
elements_type elements;
};
@@ -56,30 +48,30 @@ struct static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
// nodes traits
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
+struct node<Value, Parameters, Box, Allocators, node_variant_static_tag>
{
typedef boost::variant<
- static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>,
- static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
+ variant_leaf<Value, Parameters, Box, Allocators, node_variant_static_tag>,
+ variant_internal_node<Value, Parameters, Box, Allocators, node_variant_static_tag>
> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
+struct internal_node<Value, Parameters, Box, Allocators, node_variant_static_tag>
{
- typedef static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag> type;
+ typedef variant_internal_node<Value, Parameters, Box, Allocators, node_variant_static_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
+struct leaf<Value, Parameters, Box, Allocators, node_variant_static_tag>
{
- typedef static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag> type;
+ typedef variant_leaf<Value, Parameters, Box, Allocators, node_variant_static_tag> type;
};
// visitor traits
template <typename Value, typename Parameters, typename Box, typename Allocators, bool IsVisitableConst>
-struct visitor<Value, Parameters, Box, Allocators, node_s_mem_static_tag, IsVisitableConst>
+struct visitor<Value, Parameters, Box, Allocators, node_variant_static_tag, IsVisitableConst>
{
typedef static_visitor<> type;
};
@@ -87,9 +79,13 @@ struct visitor<Value, Parameters, Box, Allocators, node_s_mem_static_tag, IsVisi
// allocators
template <typename Allocator, typename Value, typename Parameters, typename Box>
-struct allocators<Allocator, Value, Parameters, Box, node_s_mem_static_tag>
+class allocators<Allocator, Value, Parameters, Box, node_variant_static_tag>
: public Allocator::template rebind<
- typename node<Value, Parameters, Box, allocators<Allocator, Value, Parameters, Box, node_s_mem_static_tag>, node_s_mem_static_tag>::type
+ typename node<
+ Value, Parameters, Box,
+ allocators<Allocator, Value, Parameters, Box, node_variant_static_tag>,
+ node_variant_static_tag
+ >::type
>::other
{
typedef typename Allocator::template rebind<
@@ -108,15 +104,11 @@ public:
typedef typename value_allocator_type::const_pointer const_pointer;
typedef typename Allocator::template rebind<
- typename node<Value, Parameters, Box, allocators, node_s_mem_static_tag>::type
+ typename node<Value, Parameters, Box, allocators, node_variant_static_tag>::type
>::other::pointer node_pointer;
-// typedef typename Allocator::template rebind<
-// typename internal_node<Value, Parameters, Box, allocators, node_s_mem_static_tag>::type
-// >::other::pointer internal_node_pointer;
-
typedef typename Allocator::template rebind<
- typename node<Value, Parameters, Box, allocators, node_s_mem_static_tag>::type
+ typename node<Value, Parameters, Box, allocators, node_variant_static_tag>::type
>::other node_allocator_type;
inline allocators()
@@ -161,42 +153,8 @@ public:
node_allocator_type const& node_allocator() const { return *this; }
};
-// create_node
-
-template <typename Allocators, typename Value, typename Parameters, typename Box>
-struct create_node<
- Allocators,
- static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
->
-{
- static inline typename Allocators::node_pointer
- apply(Allocators & allocators)
- {
- return create_static_node<
- typename Allocators::node_pointer,
- static_internal_node<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
- >::apply(allocators.node_allocator());
- }
-};
-
-template <typename Allocators, typename Value, typename Parameters, typename Box>
-struct create_node<
- Allocators,
- static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
->
-{
- static inline typename Allocators::node_pointer
- apply(Allocators & allocators)
- {
- return create_static_node<
- typename Allocators::node_pointer,
- static_leaf<Value, Parameters, Box, Allocators, node_s_mem_static_tag>
- >::apply(allocators.node_allocator());
- }
-};
-
}} // namespace detail::rtree
}}} // namespace boost::geometry::index
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_VARIANT_HPP
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/static_visitor.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/variant_visitor.hpp
index 9b74b1e415..e272f9e1d9 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/node/static_visitor.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/node/variant_visitor.hpp
@@ -2,16 +2,18 @@
//
// R-tree nodes static visitor related code
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_STATIC_VISITOR_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_STATIC_VISITOR_HPP
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_VISITOR_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_VISITOR_HPP
-#include <boost/variant.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/get.hpp>
+#include <boost/variant/variant.hpp>
namespace boost { namespace geometry { namespace index {
@@ -20,18 +22,18 @@ namespace detail { namespace rtree {
// nodes variants forward declarations
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
-struct static_internal_node;
+struct variant_internal_node;
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
-struct static_leaf;
+struct variant_leaf;
// nodes conversion
template <typename V, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
inline V & get(
boost::variant<
- static_leaf<Value, Parameters, Box, Allocators, Tag>,
- static_internal_node<Value, Parameters, Box, Allocators, Tag>
+ variant_leaf<Value, Parameters, Box, Allocators, Tag>,
+ variant_internal_node<Value, Parameters, Box, Allocators, Tag>
> & v)
{
return boost::get<V>(v);
@@ -42,8 +44,8 @@ inline V & get(
template <typename Visitor, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
inline void apply_visitor(Visitor & v,
boost::variant<
- static_leaf<Value, Parameters, Box, Allocators, Tag>,
- static_internal_node<Value, Parameters, Box, Allocators, Tag>
+ variant_leaf<Value, Parameters, Box, Allocators, Tag>,
+ variant_internal_node<Value, Parameters, Box, Allocators, Tag>
> & n)
{
boost::apply_visitor(v, n);
@@ -52,8 +54,8 @@ inline void apply_visitor(Visitor & v,
template <typename Visitor, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
inline void apply_visitor(Visitor & v,
boost::variant<
- static_leaf<Value, Parameters, Box, Allocators, Tag>,
- static_internal_node<Value, Parameters, Box, Allocators, Tag>
+ variant_leaf<Value, Parameters, Box, Allocators, Tag>,
+ variant_internal_node<Value, Parameters, Box, Allocators, Tag>
> const& n)
{
boost::apply_visitor(v, n);
@@ -63,4 +65,4 @@ inline void apply_visitor(Visitor & v,
}}} // namespace boost::geometry::index
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_STATIC_VISITOR_HPP
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_VISITOR_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp
index 1e3cd58d57..d49e347826 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp
@@ -1,167 +1,107 @@
// Boost.Geometry Index
//
-// R-tree nodes based on run-time polymorphism, storing std::vectors
+// R-tree nodes based on static conversion, storing dynamic-size containers
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_HPP
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
-template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct dynamic_internal_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
- : public dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
+template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
+struct weak_internal_node
+ : public weak_node<Value, Parameters, Box, Allocators, Tag>
{
- typedef typename Allocators::leaf_allocator_type::template rebind<
- rtree::ptr_pair<Box, typename Allocators::node_pointer>
- >::other elements_allocator_type;
-
- typedef boost::container::vector<
- rtree::ptr_pair<Box, typename Allocators::node_pointer>,
- elements_allocator_type
- > elements_type;
+ typedef boost::container::vector
+ <
+ rtree::ptr_pair<Box, typename Allocators::node_pointer>,
+ typename Allocators::internal_node_allocator_type::template rebind
+ <
+ rtree::ptr_pair<Box, typename Allocators::node_pointer>
+ >::other
+ > elements_type;
template <typename Al>
- inline dynamic_internal_node(Al const& al)
+ inline weak_internal_node(Al const& al)
: elements(al)
{}
- void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, false> & v) { v(*this); }
- void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, true> & v) const { v(*this); }
-
elements_type elements;
};
-template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct dynamic_leaf<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
- : public dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
+template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
+struct weak_leaf
+ : public weak_node<Value, Parameters, Box, Allocators, Tag>
{
- typedef typename Allocators::leaf_allocator_type::template rebind<
- Value
- >::other elements_allocator_type;
-
- typedef boost::container::vector<
- Value,
- elements_allocator_type
- > elements_type;
+ typedef boost::container::vector
+ <
+ Value,
+ typename Allocators::leaf_allocator_type::template rebind
+ <
+ Value
+ >::other
+ > elements_type;
template <typename Al>
- inline dynamic_leaf(Al const& al)
+ inline weak_leaf(Al const& al)
: elements(al)
{}
- void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, false> & v) { v(*this); }
- void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, true> & v) const { v(*this); }
-
elements_type elements;
};
// nodes traits
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
+struct node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag>
{
- typedef dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag> type;
+ typedef weak_node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct internal_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
+struct internal_node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag>
{
- typedef dynamic_internal_node<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag> type;
+ typedef weak_internal_node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct leaf<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag>
+struct leaf<Value, Parameters, Box, Allocators, node_weak_dynamic_tag>
{
- typedef dynamic_leaf<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag> type;
+ typedef weak_leaf<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> type;
};
// visitor traits
template <typename Value, typename Parameters, typename Box, typename Allocators, bool IsVisitableConst>
-struct visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, IsVisitableConst>
-{
- typedef dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_dynamic_tag, IsVisitableConst> type;
-};
-
-// element's indexable type
-
-template <typename Element, typename Translator>
-struct element_indexable_type
+struct visitor<Value, Parameters, Box, Allocators, node_weak_dynamic_tag, IsVisitableConst>
{
- typedef typename indexable_type<Translator>::type type;
-};
-
-template <typename First, typename Pointer, typename Translator>
-struct element_indexable_type<
- rtree::ptr_pair<First, Pointer>,
- Translator
->
-{
- typedef First type;
-};
-
-// element's indexable getter
-
-template <typename Element, typename Translator>
-typename result_type<Translator>::type
-element_indexable(Element const& el, Translator const& tr)
-{
- return tr(el);
-}
-
-template <typename First, typename Pointer, typename Translator>
-First const&
-element_indexable(rtree::ptr_pair<First, Pointer> const& el, Translator const& /*tr*/)
-{
- return el.first;
-}
-
-// nodes elements
-
-template <typename Node>
-struct elements_type
-{
- typedef typename Node::elements_type type;
-};
-
-template <typename Node>
-inline typename elements_type<Node>::type &
-elements(Node & n)
-{
- return n.elements;
-}
-
-template <typename Node>
-inline typename elements_type<Node>::type const&
-elements(Node const& n)
-{
- return n.elements;
-}
-
-// elements derived type
-template <typename Elements, typename NewValue>
-struct container_from_elements_type
-{
- typedef boost::container::vector<NewValue> type;
+ typedef weak_visitor<Value, Parameters, Box, Allocators, node_weak_dynamic_tag, IsVisitableConst> type;
};
// allocators
template <typename Allocator, typename Value, typename Parameters, typename Box>
-class allocators<Allocator, Value, Parameters, Box, node_d_mem_dynamic_tag>
+class allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>
: public Allocator::template rebind<
- typename internal_node<Value, Parameters, Box, allocators<Allocator, Value, Parameters, Box, node_d_mem_dynamic_tag>, node_d_mem_dynamic_tag>::type
+ typename internal_node<
+ Value, Parameters, Box,
+ allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>,
+ node_weak_dynamic_tag
+ >::type
>::other
, public Allocator::template rebind<
- typename leaf<Value, Parameters, Box, allocators<Allocator, Value, Parameters, Box, node_d_mem_dynamic_tag>, node_d_mem_dynamic_tag>::type
+ typename leaf<
+ Value, Parameters, Box,
+ allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>,
+ node_weak_dynamic_tag
+ >::type
>::other
{
typedef typename Allocator::template rebind<
@@ -180,19 +120,15 @@ public:
typedef typename value_allocator_type::const_pointer const_pointer;
typedef typename Allocator::template rebind<
- typename node<Value, Parameters, Box, allocators, node_d_mem_dynamic_tag>::type
+ typename node<Value, Parameters, Box, allocators, node_weak_dynamic_tag>::type
>::other::pointer node_pointer;
-// typedef typename Allocator::template rebind<
-// typename internal_node<Value, Parameters, Box, allocators, node_d_mem_dynamic_tag>::type
-// >::other::pointer internal_node_pointer;
-
typedef typename Allocator::template rebind<
- typename internal_node<Value, Parameters, Box, allocators, node_d_mem_dynamic_tag>::type
+ typename internal_node<Value, Parameters, Box, allocators, node_weak_dynamic_tag>::type
>::other internal_node_allocator_type;
typedef typename Allocator::template rebind<
- typename leaf<Value, Parameters, Box, allocators, node_d_mem_dynamic_tag>::type
+ typename leaf<Value, Parameters, Box, allocators, node_weak_dynamic_tag>::type
>::other leaf_allocator_type;
inline allocators()
@@ -248,7 +184,7 @@ public:
// create_node_impl
template <typename BaseNodePtr, typename Node>
-struct create_dynamic_node
+struct create_weak_node
{
template <typename AllocNode>
static inline BaseNodePtr apply(AllocNode & alloc_node)
@@ -261,7 +197,7 @@ struct create_dynamic_node
if ( 0 == p )
throw_runtime_error("boost::geometry::index::rtree node creation failed");
- auto_deallocator<AllocNode> deallocator(alloc_node, p);
+ scoped_deallocator<AllocNode> deallocator(p, alloc_node);
Al::construct(alloc_node, boost::addressof(*p), alloc_node);
@@ -273,7 +209,7 @@ struct create_dynamic_node
// destroy_node_impl
template <typename Node>
-struct destroy_dynamic_node
+struct destroy_weak_node
{
template <typename AllocNode, typename BaseNodePtr>
static inline void apply(AllocNode & alloc_node, BaseNodePtr n)
@@ -292,15 +228,15 @@ struct destroy_dynamic_node
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct create_node<
Allocators,
- dynamic_internal_node<Value, Parameters, Box, Allocators, Tag>
+ weak_internal_node<Value, Parameters, Box, Allocators, Tag>
>
{
static inline typename Allocators::node_pointer
apply(Allocators & allocators)
{
- return create_dynamic_node<
+ return create_weak_node<
typename Allocators::node_pointer,
- dynamic_internal_node<Value, Parameters, Box, Allocators, Tag>
+ weak_internal_node<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.internal_node_allocator());
}
};
@@ -308,15 +244,15 @@ struct create_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct create_node<
Allocators,
- dynamic_leaf<Value, Parameters, Box, Allocators, Tag>
+ weak_leaf<Value, Parameters, Box, Allocators, Tag>
>
{
static inline typename Allocators::node_pointer
apply(Allocators & allocators)
{
- return create_dynamic_node<
+ return create_weak_node<
typename Allocators::node_pointer,
- dynamic_leaf<Value, Parameters, Box, Allocators, Tag>
+ weak_leaf<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.leaf_allocator());
}
};
@@ -326,13 +262,13 @@ struct create_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct destroy_node<
Allocators,
- dynamic_internal_node<Value, Parameters, Box, Allocators, Tag>
+ weak_internal_node<Value, Parameters, Box, Allocators, Tag>
>
{
static inline void apply(Allocators & allocators, typename Allocators::node_pointer n)
{
- destroy_dynamic_node<
- dynamic_internal_node<Value, Parameters, Box, Allocators, Tag>
+ destroy_weak_node<
+ weak_internal_node<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.internal_node_allocator(), n);
}
};
@@ -340,13 +276,13 @@ struct destroy_node<
template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag>
struct destroy_node<
Allocators,
- dynamic_leaf<Value, Parameters, Box, Allocators, Tag>
+ weak_leaf<Value, Parameters, Box, Allocators, Tag>
>
{
static inline void apply(Allocators & allocators, typename Allocators::node_pointer n)
{
- destroy_dynamic_node<
- dynamic_leaf<Value, Parameters, Box, Allocators, Tag>
+ destroy_weak_node<
+ weak_leaf<Value, Parameters, Box, Allocators, Tag>
>::apply(allocators.leaf_allocator(), n);
}
};
@@ -355,4 +291,4 @@ struct destroy_node<
}}} // namespace boost::geometry::index
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_HPP
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/weak_static.hpp
index 184c48e44e..632e35678a 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/node/weak_static.hpp
@@ -1,60 +1,46 @@
// Boost.Geometry Index
//
-// R-tree nodes based on runtime-polymorphism, storing static-size containers
+// R-tree nodes based on static conversion, storing static-size containers
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_HPP
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct dynamic_internal_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
- : public dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
+struct weak_internal_node<Value, Parameters, Box, Allocators, node_weak_static_tag>
+ : public weak_node<Value, Parameters, Box, Allocators, node_weak_static_tag>
{
- typedef typename Allocators::leaf_allocator_type::template rebind<
- rtree::ptr_pair<Box, typename Allocators::node_pointer>
- >::other elements_allocator_type;
-
typedef detail::varray<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
- inline dynamic_internal_node(Alloc const&) {}
-
- void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, false> & v) { v(*this); }
- void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, true> & v) const { v(*this); }
+ inline weak_internal_node(Alloc const&) {}
elements_type elements;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct dynamic_leaf<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
- : public dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
+struct weak_leaf<Value, Parameters, Box, Allocators, node_weak_static_tag>
+ : public weak_node<Value, Parameters, Box, Allocators, node_weak_static_tag>
{
- typedef typename Allocators::leaf_allocator_type::template rebind<
- Value
- >::other elements_allocator_type;
-
typedef detail::varray<
Value,
Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
- inline dynamic_leaf(Alloc const&) {}
-
- void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, false> & v) { v(*this); }
- void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, true> & v) const { v(*this); }
+ inline weak_leaf(Alloc const&) {}
elements_type elements;
};
@@ -62,52 +48,45 @@ struct dynamic_leaf<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
// nodes traits
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct node<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
+struct node<Value, Parameters, Box, Allocators, node_weak_static_tag>
{
- typedef dynamic_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag> type;
+ typedef weak_node<Value, Parameters, Box, Allocators, node_weak_static_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct internal_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
+struct internal_node<Value, Parameters, Box, Allocators, node_weak_static_tag>
{
- typedef dynamic_internal_node<Value, Parameters, Box, Allocators, node_d_mem_static_tag> type;
+ typedef weak_internal_node<Value, Parameters, Box, Allocators, node_weak_static_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
-struct leaf<Value, Parameters, Box, Allocators, node_d_mem_static_tag>
+struct leaf<Value, Parameters, Box, Allocators, node_weak_static_tag>
{
- typedef dynamic_leaf<Value, Parameters, Box, Allocators, node_d_mem_static_tag> type;
+ typedef weak_leaf<Value, Parameters, Box, Allocators, node_weak_static_tag> type;
};
template <typename Value, typename Parameters, typename Box, typename Allocators, bool IsVisitableConst>
-struct visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, IsVisitableConst>
+struct visitor<Value, Parameters, Box, Allocators, node_weak_static_tag, IsVisitableConst>
{
- typedef dynamic_visitor<Value, Parameters, Box, Allocators, node_d_mem_static_tag, IsVisitableConst> type;
-};
-
-// elements derived type
-template <typename OldValue, size_t N, typename NewValue>
-struct container_from_elements_type<detail::varray<OldValue, N>, NewValue>
-{
- typedef detail::varray<NewValue, N> type;
+ typedef weak_visitor<Value, Parameters, Box, Allocators, node_weak_static_tag, IsVisitableConst> type;
};
// allocators
template <typename Allocator, typename Value, typename Parameters, typename Box>
-class allocators<Allocator, Value, Parameters, Box, node_d_mem_static_tag>
+class allocators<Allocator, Value, Parameters, Box, node_weak_static_tag>
: public Allocator::template rebind<
typename internal_node<
Value, Parameters, Box,
- allocators<Allocator, Value, Parameters, Box, node_d_mem_static_tag>,
- node_d_mem_static_tag
+ allocators<Allocator, Value, Parameters, Box, node_weak_static_tag>,
+ node_weak_static_tag
>::type
>::other
, public Allocator::template rebind<
typename leaf<
Value, Parameters, Box,
- allocators<Allocator, Value, Parameters, Box, node_d_mem_static_tag>,
- node_d_mem_static_tag
+ allocators<Allocator, Value, Parameters, Box, node_weak_static_tag>,
+ node_weak_static_tag
>::type
>::other
{
@@ -127,19 +106,15 @@ public:
typedef typename value_allocator_type::const_pointer const_pointer;
typedef typename Allocator::template rebind<
- typename node<Value, Parameters, Box, allocators, node_d_mem_static_tag>::type
+ typename node<Value, Parameters, Box, allocators, node_weak_static_tag>::type
>::other::pointer node_pointer;
-// typedef typename Allocator::template rebind<
-// typename internal_node<Value, Parameters, Box, allocators, node_d_mem_static_tag>::type
-// >::other::pointer internal_node_pointer;
-
typedef typename Allocator::template rebind<
- typename internal_node<Value, Parameters, Box, allocators, node_d_mem_static_tag>::type
+ typename internal_node<Value, Parameters, Box, allocators, node_weak_static_tag>::type
>::other internal_node_allocator_type;
typedef typename Allocator::template rebind<
- typename leaf<Value, Parameters, Box, allocators, node_d_mem_static_tag>::type
+ typename leaf<Value, Parameters, Box, allocators, node_weak_static_tag>::type
>::other leaf_allocator_type;
inline allocators()
@@ -196,4 +171,4 @@ public:
}}} // namespace boost::geometry::index
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_HPP
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/node/weak_visitor.hpp b/3party/boost/boost/geometry/index/detail/rtree/node/weak_visitor.hpp
new file mode 100644
index 0000000000..08d84778e6
--- /dev/null
+++ b/3party/boost/boost/geometry/index/detail/rtree/node/weak_visitor.hpp
@@ -0,0 +1,67 @@
+// Boost.Geometry Index
+//
+// R-tree nodes weak visitor and nodes base type
+//
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree {
+
+// empty visitor
+template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag, bool IsVisitableConst>
+struct weak_visitor {};
+
+// node
+
+template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
+struct weak_node {};
+
+// nodes variants forward declarations
+
+template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
+struct weak_internal_node;
+
+template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
+struct weak_leaf;
+
+// nodes conversion
+
+template <typename Derived, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
+inline Derived & get(weak_node<Value, Parameters, Box, Allocators, Tag> & n)
+{
+ return static_cast<Derived&>(n);
+}
+
+// apply visitor
+
+template <typename Visitor, typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
+inline void apply_visitor(Visitor & v,
+ weak_node<Value, Parameters, Box, Allocators, Tag> & n,
+ bool is_internal_node)
+{
+ BOOST_GEOMETRY_INDEX_ASSERT(&n, "null ptr");
+ if ( is_internal_node )
+ {
+ typedef weak_internal_node<Value, Parameters, Box, Allocators, Tag> internal_node;
+ v(get<internal_node>(n));
+ }
+ else
+ {
+ typedef weak_leaf<Value, Parameters, Box, Allocators, Tag> leaf;
+ v(get<leaf>(n));
+ }
+}
+
+}} // namespace detail::rtree
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_DYNAMIC_VISITOR_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/options.hpp b/3party/boost/boost/geometry/index/detail/rtree/options.hpp
index b7947402cb..ff772834d7 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/options.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/options.hpp
@@ -2,7 +2,7 @@
//
// R-tree options, algorithms, parameters
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -35,10 +35,10 @@ struct quadratic_tag {};
struct rstar_tag {};
// NodeTag
-struct node_d_mem_dynamic_tag {};
-struct node_d_mem_static_tag {};
-struct node_s_mem_dynamic_tag {};
-struct node_s_mem_static_tag {};
+struct node_variant_dynamic_tag {};
+struct node_variant_static_tag {};
+//struct node_weak_dynamic_tag {};
+//struct node_weak_static_tag {};
template <typename Parameters, typename InsertTag, typename ChooseNextNodeTag, typename SplitTag, typename RedistributeTag, typename NodeTag>
struct options
@@ -66,7 +66,7 @@ struct options_type< index::linear<MaxElements, MinElements> >
choose_by_content_diff_tag,
split_default_tag,
linear_tag,
- node_s_mem_static_tag
+ node_variant_static_tag
> type;
};
@@ -79,7 +79,7 @@ struct options_type< index::quadratic<MaxElements, MinElements> >
choose_by_content_diff_tag,
split_default_tag,
quadratic_tag,
- node_s_mem_static_tag
+ node_variant_static_tag
> type;
};
@@ -92,7 +92,7 @@ struct options_type< index::rstar<MaxElements, MinElements, OverlapCostThreshold
choose_by_overlap_diff_tag,
split_default_tag,
rstar_tag,
- node_s_mem_static_tag
+ node_variant_static_tag
> type;
};
@@ -105,7 +105,7 @@ struct options_type< index::rstar<MaxElements, MinElements, OverlapCostThreshold
// choose_by_content_diff_tag, // change it?
// split_kmeans_tag,
// int, // dummy tag - not used for now
-// node_s_mem_static_tag
+// node_variant_static_tag
// > type;
//};
@@ -118,7 +118,7 @@ struct options_type< index::dynamic_linear >
choose_by_content_diff_tag,
split_default_tag,
linear_tag,
- node_s_mem_dynamic_tag
+ node_variant_dynamic_tag
> type;
};
@@ -131,7 +131,7 @@ struct options_type< index::dynamic_quadratic >
choose_by_content_diff_tag,
split_default_tag,
quadratic_tag,
- node_s_mem_dynamic_tag
+ node_variant_dynamic_tag
> type;
};
@@ -144,7 +144,7 @@ struct options_type< index::dynamic_rstar >
choose_by_overlap_diff_tag,
split_default_tag,
rstar_tag,
- node_s_mem_dynamic_tag
+ node_variant_dynamic_tag
> type;
};
diff --git a/3party/boost/boost/geometry/index/detail/rtree/pack_create.hpp b/3party/boost/boost/geometry/index/detail/rtree/pack_create.hpp
index e3ac16aefa..b7be41ab2b 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/pack_create.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/pack_create.hpp
@@ -2,7 +2,7 @@
//
// R-tree initial packing
//
-// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -122,14 +122,14 @@ class pack
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename Allocators::node_pointer node_pointer;
- typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
+ typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::size_type size_type;
- typedef typename traits::point_type<Box>::type point_type;
- typedef typename traits::coordinate_type<point_type>::type coordinate_type;
+ typedef typename geometry::point_type<Box>::type point_type;
+ typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
typedef typename detail::default_content_result<Box>::type content_type;
typedef typename Options::parameters_type parameters_type;
- static const std::size_t dimension = traits::dimension<point_type>::value;
+ static const std::size_t dimension = geometry::dimension<point_type>::value;
typedef typename rtree::container_from_elements_type<
typename rtree::elements_type<leaf>::type,
@@ -161,10 +161,21 @@ public:
geometry::assign_inverse(hint_box);
for ( ; first != last ; ++first )
{
- geometry::expand(hint_box, translator(*first));
+ // NOTE: support for iterators not returning true references adapted
+ // to Geometry concept and default translator returning true reference
+ // An alternative would be to dereference the iterator and translate
+ // in one expression each time the indexable was needed.
+ typename std::iterator_traits<InIt>::reference in_ref = *first;
+ typename Translator::result_type indexable = translator(in_ref);
+
+ // NOTE: added for consistency with insert()
+ // CONSIDER: alternative - ignore invalid indexable or throw an exception
+ BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(indexable), "Indexable is invalid");
+
+ geometry::expand(hint_box, indexable);
point_type pt;
- geometry::centroid(translator(*first), pt);
+ geometry::centroid(indexable, pt);
entries.push_back(std::make_pair(pt, first));
}
@@ -187,17 +198,19 @@ private:
internal_element per_level(EIt first, EIt last, Box const& hint_box, std::size_t values_count, subtree_elements_counts const& subtree_counts,
parameters_type const& parameters, Translator const& translator, Allocators & allocators)
{
- BOOST_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count);
+ BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count,
+ "unexpected parameters");
if ( subtree_counts.maxc <= 1 )
{
// ROOT or LEAF
- BOOST_ASSERT(values_count <= parameters.get_max_elements());
+ BOOST_GEOMETRY_INDEX_ASSERT(values_count <= parameters.get_max_elements(),
+ "too big number of elements");
// if !root check m_parameters.get_min_elements() <= count
// create new leaf node
node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A)
- node_auto_ptr auto_remover(n, allocators);
+ subtree_destroyer auto_remover(n, allocators);
leaf & l = rtree::get<leaf>(*n);
// reserve space for values
@@ -207,8 +220,11 @@ private:
geometry::assign_inverse(elements_box);
for ( ; first != last ; ++first )
{
- rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
+ // NOTE: push_back() must be called at the end in order to support move_iterator.
+ // The iterator is dereferenced 2x (no temporary reference) to support
+ // non-true reference types and move_iterator without boost::forward<>.
geometry::expand(elements_box, translator(*(first->second)));
+ rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
}
auto_remover.release();
@@ -222,7 +238,7 @@ private:
// create new internal node
node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A)
- node_auto_ptr auto_remover(n, allocators);
+ subtree_destroyer auto_remover(n, allocators);
internal_node & in = rtree::get<internal_node>(*n);
// reserve space for values
@@ -248,9 +264,11 @@ private:
internal_elements & elements, Box & elements_box,
parameters_type const& parameters, Translator const& translator, Allocators & allocators)
{
- BOOST_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count);
+ BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count,
+ "unexpected parameters");
- BOOST_ASSERT_MSG( subtree_counts.minc <= values_count, "too small number of elements");
+ BOOST_GEOMETRY_INDEX_ASSERT(subtree_counts.minc <= values_count,
+ "too small number of elements");
// only one packet
if ( values_count <= subtree_counts.maxc )
@@ -262,7 +280,7 @@ private:
// in case if push_back() do throw here
// and even if this is not probable (previously reserved memory, nonthrowing pairs copy)
// this case is also tested by exceptions test.
- node_auto_ptr auto_remover(el.second, allocators);
+ subtree_destroyer auto_remover(el.second, allocators);
// this container should have memory allocated, reserve() called outside
elements.push_back(el); // MAY THROW (A?,C) - however in normal conditions shouldn't
auto_remover.release();
@@ -343,7 +361,7 @@ private:
{
if ( subtree_counts.minc <= r ) // e.g. 10 <= 2 == false
{
- //BOOST_ASSERT_MSG(0 < n, "unexpected value");
+ //BOOST_GEOMETRY_INDEX_ASSERT(0 < n, "unexpected value");
median_count = ((n+1)/2) * subtree_counts.maxc; // if calculated ((2+1)/2) * 25 which would be ok, but not in all cases
}
else // r < subtree_counts.second // e.g. 2 < 10 == true
@@ -354,7 +372,7 @@ private:
if ( r == 0 ) // e.g. false
{
// n can't be equal to 0 because then there wouldn't be any element in the other node
- //BOOST_ASSERT_MSG(0 < n, "unexpected value");
+ //BOOST_GEOMETRY_INDEX_ASSERT(0 < n, "unexpected value");
median_count = ((n+1)/2) * subtree_counts.maxc; // if calculated ((1+1)/2) * 25 which would be ok, but not in all cases
}
else
diff --git a/3party/boost/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp b/3party/boost/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp
index c7e948a05e..634d879864 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp
@@ -28,60 +28,56 @@ namespace detail { namespace rtree {
namespace quadratic {
-template <typename Elements, typename Parameters, typename Translator, typename Box>
-struct pick_seeds
+template <typename Box, typename Elements, typename Parameters, typename Translator>
+inline void pick_seeds(Elements const& elements,
+ Parameters const& parameters,
+ Translator const& tr,
+ size_t & seed1,
+ size_t & seed2)
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef Box box_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
typedef index::detail::bounded_view<indexable_type, box_type> bounded_indexable_view;
- static inline void apply(Elements const& elements,
- Parameters const& parameters,
- Translator const& tr,
- size_t & seed1,
- size_t & seed2)
- {
- const size_t elements_count = parameters.get_max_elements() + 1;
- BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "wrong number of elements");
- BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
+ const size_t elements_count = parameters.get_max_elements() + 1;
+ BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "wrong number of elements");
+ BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
- content_type greatest_free_content = 0;
- seed1 = 0;
- seed2 = 1;
+ content_type greatest_free_content = 0;
+ seed1 = 0;
+ seed2 = 1;
- for ( size_t i = 0 ; i < elements_count - 1 ; ++i )
+ for ( size_t i = 0 ; i < elements_count - 1 ; ++i )
+ {
+ for ( size_t j = i + 1 ; j < elements_count ; ++j )
{
- for ( size_t j = i + 1 ; j < elements_count ; ++j )
- {
- indexable_type const& ind1 = rtree::element_indexable(elements[i], tr);
- indexable_type const& ind2 = rtree::element_indexable(elements[j], tr);
-
- box_type enlarged_box;
- //geometry::convert(ind1, enlarged_box);
- detail::bounds(ind1, enlarged_box);
- geometry::expand(enlarged_box, ind2);
-
- bounded_indexable_view bounded_ind1(ind1);
- bounded_indexable_view bounded_ind2(ind2);
- content_type free_content = ( index::detail::content(enlarged_box)
- - index::detail::content(bounded_ind1) )
- - index::detail::content(bounded_ind2);
+ indexable_type const& ind1 = rtree::element_indexable(elements[i], tr);
+ indexable_type const& ind2 = rtree::element_indexable(elements[j], tr);
+
+ box_type enlarged_box;
+ //geometry::convert(ind1, enlarged_box);
+ detail::bounds(ind1, enlarged_box);
+ geometry::expand(enlarged_box, ind2);
+
+ bounded_indexable_view bounded_ind1(ind1);
+ bounded_indexable_view bounded_ind2(ind2);
+ content_type free_content = ( index::detail::content(enlarged_box)
+ - index::detail::content(bounded_ind1) )
+ - index::detail::content(bounded_ind2);
- if ( greatest_free_content < free_content )
- {
- greatest_free_content = free_content;
- seed1 = i;
- seed2 = j;
- }
+ if ( greatest_free_content < free_content )
+ {
+ greatest_free_content = free_content;
+ seed1 = i;
+ seed2 = j;
}
}
-
- ::boost::ignore_unused_variable_warning(parameters);
}
-};
+
+ ::boost::ignore_unused_variable_warning(parameters);
+}
} // namespace quadratic
@@ -114,20 +110,17 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
BOOST_GEOMETRY_INDEX_ASSERT(elements1.size() == parameters.get_max_elements() + 1, "unexpected elements number");
- // copy original elements
- // TODO: use container_from_elements_type for std::allocator
- elements_type elements_copy(elements1); // MAY THROW, STRONG (alloc, copy)
- elements_type elements_backup(elements1); // MAY THROW, STRONG (alloc, copy)
+ // copy original elements - use in-memory storage (std::allocator)
+ // TODO: move if noexcept
+ typedef typename rtree::container_from_elements_type<elements_type, element_type>::type
+ container_type;
+ container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy)
+ container_type elements_backup(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy)
// calculate initial seeds
size_t seed1 = 0;
size_t seed2 = 0;
- quadratic::pick_seeds<
- elements_type,
- parameters_type,
- Translator,
- Box
- >::apply(elements_copy, parameters, translator, seed1, seed2);
+ quadratic::pick_seeds<Box>(elements_copy, parameters, translator, seed1, seed2);
// prepare nodes' elements containers
elements1.clear();
@@ -170,7 +163,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
// redistribute the rest of the elements
while ( !elements_copy.empty() )
{
- typename elements_type::reverse_iterator el_it = elements_copy.rbegin();
+ typename container_type::reverse_iterator el_it = elements_copy.rbegin();
bool insert_into_group1 = false;
size_t elements1_count = elements1.size();
@@ -227,7 +220,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
}
BOOST_GEOMETRY_INDEX_ASSERT(!elements_copy.empty(), "expected more elements");
- typename elements_type::iterator el_it_base = el_it.base();
+ typename container_type::iterator el_it_base = el_it.base();
rtree::move_from_back(elements_copy, --el_it_base); // MAY THROW, STRONG (copy)
elements_copy.pop_back();
diff --git a/3party/boost/boost/geometry/index/detail/rtree/query_iterators.hpp b/3party/boost/boost/geometry/index/detail/rtree/query_iterators.hpp
index 8366fca191..83be106b8b 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/query_iterators.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/query_iterators.hpp
@@ -2,7 +2,7 @@
//
// R-tree query iterators
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,9 +11,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_VIRTUAL
-//#define BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_FUNCTION
-//#define BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_TYPE_ERASURE
+#include <boost/scoped_ptr.hpp>
+
//#define BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
@@ -21,7 +20,7 @@ namespace boost { namespace geometry { namespace index { namespace detail { name
template <typename Value, typename Allocators>
struct end_query_iterator
{
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
@@ -29,27 +28,27 @@ struct end_query_iterator
reference operator*() const
{
- BOOST_ASSERT_MSG(false, "iterator not dereferencable");
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
pointer p(0);
return *p;
}
const value_type * operator->() const
{
- BOOST_ASSERT_MSG(false, "iterator not dereferencable");
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
const value_type * p = 0;
return p;
}
end_query_iterator & operator++()
{
- BOOST_ASSERT_MSG(false, "iterator not incrementable");
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
return *this;
}
end_query_iterator operator++(int)
{
- BOOST_ASSERT_MSG(false, "iterator not incrementable");
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
return *this;
}
@@ -66,12 +65,15 @@ class spatial_query_iterator
typedef typename visitor_type::node_pointer node_pointer;
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
+ inline spatial_query_iterator()
+ {}
+
inline spatial_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
@@ -131,12 +133,15 @@ class distance_query_iterator
typedef typename visitor_type::node_pointer node_pointer;
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
+ inline distance_query_iterator()
+ {}
+
inline distance_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
@@ -189,25 +194,19 @@ private:
visitor_type m_visitor;
};
+
template <typename L, typename R>
inline bool operator!=(L const& l, R const& r)
{
return !(l == r);
}
-}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
-
-#if defined(BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_VIRTUAL) || defined(BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_FUNCTION)
-
-#if defined(BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_VIRTUAL)
-
-namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
template <typename Value, typename Allocators>
class query_iterator_base
{
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
@@ -230,12 +229,13 @@ class query_iterator_wrapper
typedef query_iterator_base<Value, Allocators> base_t;
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
+ query_iterator_wrapper() : m_iterator() {}
explicit query_iterator_wrapper(Iterator const& it) : m_iterator(it) {}
virtual base_t * clone() const { return new query_iterator_wrapper(m_iterator); }
@@ -246,7 +246,7 @@ public:
virtual bool equals(base_t const& r) const
{
const query_iterator_wrapper * p = dynamic_cast<const query_iterator_wrapper *>(boost::addressof(r));
- BOOST_ASSERT_MSG(p, "those iterators can't be compared");
+ BOOST_GEOMETRY_INDEX_ASSERT(p, "iterators can't be compared");
return m_iterator == p->m_iterator;
}
@@ -254,88 +254,22 @@ private:
Iterator m_iterator;
};
-#elif defined(BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_FUNCTION)
-
-#include <boost/function.hpp>
-#include <boost/bind.hpp>
-
-namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
-
-template <typename Value, typename Allocators>
-class query_iterator_base
-{
-public:
- typedef std::input_iterator_tag iterator_category;
- typedef Value value_type;
- typedef typename Allocators::const_reference reference;
- typedef typename Allocators::difference_type difference_type;
- typedef typename Allocators::const_pointer pointer;
-
- virtual ~query_iterator_base() {}
-
- boost::function<query_iterator_base*()> clone;
- boost::function<bool()> is_end;
- boost::function<reference()> dereference;
- boost::function<void()> increment;
- boost::function<bool(query_iterator_base const&)> equals;
-};
-
-template <typename Value, typename Allocators, typename Iterator>
-class query_iterator_wrapper
- : public query_iterator_base<Value, Allocators>
-{
- typedef query_iterator_base<Value, Allocators> base_t;
-
-public:
- typedef std::input_iterator_tag iterator_category;
- typedef Value value_type;
- typedef typename Allocators::const_reference reference;
- typedef typename Allocators::difference_type difference_type;
- typedef typename Allocators::const_pointer pointer;
-
- explicit query_iterator_wrapper(Iterator const& it)
- : m_iterator(it)
- {
- base_t::clone = boost::bind(&query_iterator_wrapper::clone_, this);
- base_t::is_end = boost::bind(&query_iterator_wrapper::is_end_, this);
- base_t::dereference = boost::bind(&query_iterator_wrapper::dereference_, this);
- base_t::increment = boost::bind(&query_iterator_wrapper::increment_, this);
- base_t::equals = boost::bind(&query_iterator_wrapper::equals_, this, _1);
- }
-
-private:
- base_t * clone_() const { return new query_iterator_wrapper(m_iterator); }
-
- bool is_end_() const { return m_iterator == end_query_iterator<Value, Allocators>(); }
- reference dereference_() const { return *m_iterator; }
- void increment_() { ++m_iterator; }
- bool equals_(base_t const& r) const
- {
- const query_iterator_wrapper * p = dynamic_cast<const query_iterator_wrapper *>(boost::addressof(r));
- BOOST_ASSERT_MSG(p, "those iterators can't be compared");
- return m_iterator == p->m_iterator;
- }
-
-private:
- Iterator m_iterator;
-};
-
-#endif
template <typename Value, typename Allocators>
class query_iterator
{
typedef query_iterator_base<Value, Allocators> iterator_base;
- typedef std::auto_ptr<iterator_base> iterator_ptr;
+ typedef boost::scoped_ptr<iterator_base> iterator_ptr;
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
- query_iterator() {}
+ query_iterator()
+ {}
template <typename It>
query_iterator(It const& it)
@@ -353,21 +287,24 @@ public:
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
query_iterator & operator=(query_iterator const& o)
{
- m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
+ if ( this != boost::addressof(o) )
+ {
+ m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
+ }
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
query_iterator(query_iterator && o)
- : m_ptr(o.m_ptr.get())
+ : m_ptr(0)
{
- o.m_ptr.release();
+ m_ptr.swap(o.m_ptr);
}
query_iterator & operator=(query_iterator && o)
{
if ( this != boost::addressof(o) )
{
- m_ptr.reset(o.m_ptr.get());
- o.m_ptr.release();
+ m_ptr.swap(o.m_ptr);
+ o.m_ptr.reset();
}
return *this;
}
@@ -378,20 +315,23 @@ private:
public:
query_iterator & operator=(BOOST_COPY_ASSIGN_REF(query_iterator) o)
{
- m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
+ if ( this != boost::addressof(o) )
+ {
+ m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
+ }
return *this;
}
query_iterator(BOOST_RV_REF(query_iterator) o)
- : m_ptr(o.m_ptr.get())
+ : m_ptr(0)
{
- o.m_ptr.release();
+ m_ptr.swap(o.m_ptr);
}
query_iterator & operator=(BOOST_RV_REF(query_iterator) o)
{
if ( this != boost::addressof(o) )
{
- m_ptr.reset(o.m_ptr.get());
- o.m_ptr.release();
+ m_ptr.swap(o.m_ptr);
+ o.m_ptr.reset();
}
return *this;
}
@@ -444,156 +384,4 @@ private:
}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
-#elif defined(BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_TYPE_ERASURE)
-
-#include <boost/type_erasure/any.hpp>
-#include <boost/type_erasure/operators.hpp>
-#include <boost/type_erasure/is_empty.hpp>
-
-namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
-
-template<typename T, typename Value, typename Allocators>
-struct single_pass_iterator_concept :
- ::boost::mpl::vector<
- ::boost::type_erasure::copy_constructible<T>,
- ::boost::type_erasure::equality_comparable<T>,
- ::boost::type_erasure::dereferenceable<typename Allocators::const_reference, T>,
- ::boost::type_erasure::assignable<T>,
- ::boost::type_erasure::incrementable<T>,
- ::boost::type_erasure::equality_comparable<T, end_query_iterator<Value, Allocators> >,
- ::boost::type_erasure::relaxed // default ctor
- >
-{};
-
-template <typename Value, typename Allocators>
-struct single_pass_iterator_type
-{
- typedef ::boost::type_erasure::any<
- single_pass_iterator_concept<
- ::boost::type_erasure::_self, Value, Allocators
- >
- > type;
-};
-
-}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
-
-namespace boost { namespace type_erasure {
-
-template<typename T, typename Value, typename Allocators, typename Base>
-struct concept_interface<
- ::boost::geometry::index::detail::rtree::single_pass_iterator_concept<
- T, Value, Allocators
- >, Base, T>
- : Base
-{
- typedef Value value_type;
- typedef typename Allocators::const_reference reference;
- typedef typename Allocators::const_pointer pointer;
- typedef typename Allocators::difference_type difference_type;
- typedef ::std::input_iterator_tag iterator_category;
-};
-
-}} // boost::type_erasure
-
-namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
-
-template <typename Value, typename Allocators>
-class query_iterator
-{
-public:
- typedef std::input_iterator_tag iterator_category;
- typedef Value value_type;
- typedef typename Allocators::const_reference reference;
- typedef typename Allocators::difference_type difference_type;
- typedef typename Allocators::const_pointer pointer;
-
-private:
- typedef typename rtree::single_pass_iterator_type<Value, Allocators>::type iterator_type;
-
-public:
-
- query_iterator() {}
-
- template <typename It>
- query_iterator(It const& it)
- : m_iterator(it)
- {}
-
- query_iterator(end_query_iterator<Value, Allocators> const& /*it*/)
- {}
-
-#ifdef BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
-private:
- BOOST_COPYABLE_AND_MOVABLE(query_iterator)
-public:
- query_iterator(query_iterator const& o)
- : m_iterator(o.m_iterator)
- {}
- query_iterator & operator=(BOOST_COPY_ASSIGN_REF(query_iterator) o)
- {
- m_iterator = o.m_iterator;
- return *this;
- }
- query_iterator(BOOST_RV_REF(query_iterator) o)
- : m_iterator(boost::move(o.m_iterator))
- {}
- query_iterator & operator=(BOOST_RV_REF(query_iterator) o)
- {
- if ( this != boost::addressof(o) )
- {
- m_iterator = boost::move(o.m_iterator);
- }
- return *this;
- }
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
-
- reference operator*() const
- {
- return *m_iterator;
- }
-
- const value_type * operator->() const
- {
- return boost::addressof(*m_iterator);
- }
-
- query_iterator & operator++()
- {
- ++m_iterator;
- return *this;
- }
-
- query_iterator operator++(int)
- {
- query_iterator temp = *this;
- ++m_iterator;
- return temp;
- }
-
- friend bool operator==(query_iterator const& l, query_iterator const& r)
- {
- if ( !::boost::type_erasure::is_empty(l.m_iterator) )
- {
- if ( !::boost::type_erasure::is_empty(r.m_iterator) )
- return l.m_iterator == r.m_iterator;
- else
- return l.m_iterator == end_query_iterator<Value, Allocators>();
- }
- else
- {
- if ( !::boost::type_erasure::is_empty(r.m_iterator) )
- return r.m_iterator == end_query_iterator<Value, Allocators>();
- else
- return true;
- }
- }
-
-private:
- iterator_type m_iterator;
-};
-
-}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
-
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_TYPE_ERASURE
-
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp b/3party/boost/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp
index 89dd5e5ff4..7a96986a27 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp
@@ -2,7 +2,7 @@
//
// R-tree R*-tree next node choosing algorithm implementation
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -54,12 +54,6 @@ public:
// children are leafs
if ( node_relative_level <= 1 )
{
- /*if ( 0 < parameters.get_overlap_cost_threshold() &&
- parameters.get_overlap_cost_threshold() < children.size() )
- return choose_by_nearly_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold());
- else
- return choose_by_minimum_overlap_cost(children, indexable);*/
-
return choose_by_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold());
}
// children are internal nodes
@@ -112,31 +106,36 @@ private:
if ( min_content_diff < -std::numeric_limits<double>::epsilon() || std::numeric_limits<double>::epsilon() < min_content_diff )
{
+ size_t first_n_children_count = children_count;
if ( 0 < overlap_cost_threshold && overlap_cost_threshold < children.size() )
{
- // calculate nearly minimum overlap cost
-
- // sort by content_diff
- std::partial_sort(children_contents.begin(), children_contents.begin() + overlap_cost_threshold, children_contents.end(), content_diff_less);
- choosen_index = choose_by_minimum_overlap_cost_sorted_by_content(children, indexable, children_count, overlap_cost_threshold, children_contents);
+ first_n_children_count = overlap_cost_threshold;
+ // rearrange by content_diff
+ // in order to calculate nearly minimum overlap cost
+ std::nth_element(children_contents.begin(), children_contents.begin() + first_n_children_count, children_contents.end(), content_diff_less);
}
- else
- {
- // calculate minimum overlap cost
- choosen_index = choose_by_minimum_overlap_cost_unsorted_by_content(children, indexable, children_count, children_contents);
- }
+ // calculate minimum or nearly minimum overlap cost
+ choosen_index = choose_by_minimum_overlap_cost_first_n(children, indexable, first_n_children_count, children_count, children_contents);
}
return choosen_index;
}
+ static inline bool content_diff_less(boost::tuple<size_t, content_type, content_type> const& p1, boost::tuple<size_t, content_type, content_type> const& p2)
+ {
+ return boost::get<1>(p1) < boost::get<1>(p2) ||
+ (boost::get<1>(p1) == boost::get<1>(p2) && boost::get<2>(p1) < boost::get<2>(p2));
+ }
+
template <typename Indexable, typename ChildrenContents>
- static inline size_t choose_by_minimum_overlap_cost_unsorted_by_content(children_type const& children,
- Indexable const& indexable,
- size_t children_count,
- ChildrenContents const& children_contents)
+ static inline size_t choose_by_minimum_overlap_cost_first_n(children_type const& children,
+ Indexable const& indexable,
+ size_t const first_n_children_count,
+ size_t const children_count,
+ ChildrenContents const& children_contents)
{
+ BOOST_GEOMETRY_INDEX_ASSERT(first_n_children_count <= children_count, "unexpected value");
BOOST_GEOMETRY_INDEX_ASSERT(children_contents.size() == children_count, "unexpected number of elements");
// choose index with smallest overlap change value, or content change or smallest content
@@ -146,7 +145,7 @@ private:
content_type smallest_content = (std::numeric_limits<content_type>::max)();
// for each child node
- for (size_t i = 0 ; i < children_count ; ++i )
+ for (size_t i = 0 ; i < first_n_children_count ; ++i )
{
child_type const& ch_i = children[i];
@@ -189,198 +188,6 @@ private:
return choosen_index;
}
-
- template <typename Indexable, typename ChildrenContents>
- static inline size_t choose_by_minimum_overlap_cost_sorted_by_content(children_type const& children,
- Indexable const& indexable,
- size_t children_count,
- size_t overlap_cost_threshold,
- ChildrenContents const& children_contents)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(overlap_cost_threshold < children_count, "unexpected value");
- BOOST_GEOMETRY_INDEX_ASSERT(children_count == children_contents.size(), "unexpected number of elements");
-
- // for overlap_cost_threshold child nodes find the one with smallest overlap value
- size_t choosen_index = 0;
- content_type smallest_overlap_diff = (std::numeric_limits<content_type>::max)();
-
- // for each node
- for (size_t i = 0 ; i < overlap_cost_threshold ; ++i )
- {
- size_t child_index = boost::get<0>(children_contents[i]);
-
- typedef typename children_type::value_type child_type;
- child_type const& ch_i = children[child_index];
-
- Box box_exp(ch_i.first);
- // calculate expanded box of child node ch_i
- geometry::expand(box_exp, indexable);
-
- content_type overlap_diff = 0;
-
- // calculate overlap
- for ( size_t j = 0 ; j < children_count ; ++j )
- {
- if ( child_index != j )
- {
- child_type const& ch_j = children[j];
-
- content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
- if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
- {
- overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
- }
- }
- }
-
- // update result
- if ( overlap_diff < smallest_overlap_diff )
- {
- smallest_overlap_diff = overlap_diff;
- choosen_index = child_index;
- }
- }
-
- return choosen_index;
- }
-
- //template <typename Indexable>
- //static inline size_t choose_by_minimum_overlap_cost(children_type const& children,
- // Indexable const& indexable)
- //{
- // size_t children_count = children.size();
-
- // // choose index with smallest overlap change value, or content change or smallest content
- // size_t choosen_index = 0;
- // content_type smallest_overlap_diff = (std::numeric_limits<content_type>::max)();
- // content_type smallest_content_diff = (std::numeric_limits<content_type>::max)();
- // content_type smallest_content = (std::numeric_limits<content_type>::max)();
-
- // // for each child node
- // for (size_t i = 0 ; i < children_count ; ++i )
- // {
- // child_type const& ch_i = children[i];
-
- // Box box_exp(ch_i.first);
- // // calculate expanded box of child node ch_i
- // geometry::expand(box_exp, indexable);
-
- // // calculate content and content diff
- // content_type content = index::detail::content(box_exp);
- // content_type content_diff = content - index::detail::content(ch_i.first);
-
- // content_type overlap_diff = 0;
- //
- // // calculate overlap
- // for ( size_t j = 0 ; j < children_count ; ++j )
- // {
- // if ( i != j )
- // {
- // child_type const& ch_j = children[j];
-
- // content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
- // if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
- // {
- // overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
- // }
- // }
- // }
-
- // // update result
- // if ( overlap_diff < smallest_overlap_diff ||
- // ( overlap_diff == smallest_overlap_diff && ( content_diff < smallest_content_diff ||
- // ( content_diff == smallest_content_diff && content < smallest_content ) )
- // ) )
- // {
- // smallest_overlap_diff = overlap_diff;
- // smallest_content_diff = content_diff;
- // smallest_content = content;
- // choosen_index = i;
- // }
- // }
-
- // return choosen_index;
- //}
-
- //template <typename Indexable>
- //static inline size_t choose_by_nearly_minimum_overlap_cost(children_type const& children,
- // Indexable const& indexable,
- // size_t overlap_cost_threshold)
- //{
- // const size_t children_count = children.size();
-
- // // create container of children sorted by content enlargement needed to include the new value
- // std::vector< boost::tuple<size_t, content_type, content_type> > sorted_children(children_count);
- // for ( size_t i = 0 ; i < children_count ; ++i )
- // {
- // child_type const& ch_i = children[i];
-
- // // expanded child node's box
- // Box box_exp(ch_i.first);
- // geometry::expand(box_exp, indexable);
-
- // // areas difference
- // content_type content = index::detail::content(box_exp);
- // content_type content_diff = content - index::detail::content(ch_i.first);
-
- // sorted_children[i] = boost::make_tuple(i, content_diff, content);
- // }
-
- // BOOST_GEOMETRY_INDEX_ASSERT(overlap_cost_threshold <= children_count, "there is not enough children");
-
- // // sort by content_diff
- // //std::sort(sorted_children.begin(), sorted_children.end(), content_diff_less);
- // std::partial_sort(sorted_children.begin(), sorted_children.begin() + overlap_cost_threshold, sorted_children.end(), content_diff_less);
-
- // // for overlap_cost_threshold child nodes find the one with smallest overlap value
- // size_t choosen_index = 0;
- // content_type smallest_overlap_diff = (std::numeric_limits<content_type>::max)();
-
- // // for each node
- // for (size_t i = 0 ; i < overlap_cost_threshold ; ++i )
- // {
- // size_t child_index = boost::get<0>(sorted_children[i]);
-
- // typedef typename children_type::value_type child_type;
- // child_type const& ch_i = children[child_index];
-
- // Box box_exp(ch_i.first);
- // // calculate expanded box of child node ch_i
- // geometry::expand(box_exp, indexable);
-
- // content_type overlap_diff = 0;
-
- // // calculate overlap
- // for ( size_t j = 0 ; j < children_count ; ++j )
- // {
- // if ( child_index != j )
- // {
- // child_type const& ch_j = children[j];
-
- // content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
- // if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
- // {
- // overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
- // }
- // }
- // }
-
- // // update result
- // if ( overlap_diff < smallest_overlap_diff )
- // {
- // smallest_overlap_diff = overlap_diff;
- // choosen_index = child_index;
- // }
- // }
-
- // return choosen_index;
- //}
-
- static inline bool content_diff_less(boost::tuple<size_t, content_type, content_type> const& p1, boost::tuple<size_t, content_type, content_type> const& p2)
- {
- return boost::get<1>(p1) < boost::get<1>(p2) ||
- (boost::get<1>(p1) == boost::get<1>(p2) && boost::get<2>(p1) < boost::get<2>(p2));
- }
template <typename Indexable>
static inline size_t choose_by_minimum_content_cost(children_type const& children, Indexable const& indexable)
diff --git a/3party/boost/boost/geometry/index/detail/rtree/rstar/insert.hpp b/3party/boost/boost/geometry/index/detail/rtree/rstar/insert.hpp
index c903d6ca2a..ce92140872 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/rstar/insert.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/rstar/insert.hpp
@@ -178,14 +178,15 @@ struct level_insert_base
typedef typename Options::parameters_type parameters_type;
typedef typename Allocators::node_pointer node_pointer;
+ typedef typename Allocators::size_type size_type;
inline level_insert_base(node_pointer & root,
- size_t & leafs_level,
+ size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
- size_t relative_level)
+ size_type relative_level)
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
, result_relative_level(0)
{}
@@ -240,7 +241,7 @@ struct level_insert_base
}
}
- size_t result_relative_level;
+ size_type result_relative_level;
result_elements_type result_elements;
};
@@ -256,14 +257,15 @@ struct level_insert
typedef typename Options::parameters_type parameters_type;
typedef typename Allocators::node_pointer node_pointer;
+ typedef typename Allocators::size_type size_type;
inline level_insert(node_pointer & root,
- size_t & leafs_level,
+ size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
- size_t relative_level)
+ size_type relative_level)
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
{}
@@ -341,14 +343,15 @@ struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocat
typedef typename Options::parameters_type parameters_type;
typedef typename Allocators::node_pointer node_pointer;
+ typedef typename Allocators::size_type size_type;
inline level_insert(node_pointer & root,
- size_t & leafs_level,
+ size_type & leafs_level,
Value const& v,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
- size_t relative_level)
+ size_type relative_level)
: base(root, leafs_level, v, parameters, translator, allocators, relative_level)
{}
@@ -396,14 +399,15 @@ struct level_insert<0, Value, Value, Options, Translator, Box, Allocators>
typedef typename Options::parameters_type parameters_type;
typedef typename Allocators::node_pointer node_pointer;
+ typedef typename Allocators::size_type size_type;
inline level_insert(node_pointer & root,
- size_t & leafs_level,
+ size_type & leafs_level,
Value const& v,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
- size_t relative_level)
+ size_type relative_level)
: base(root, leafs_level, v, parameters, translator, allocators, relative_level)
{}
@@ -453,22 +457,24 @@ class insert<Element, Value, Options, Translator, Box, Allocators, insert_reinse
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename Allocators::node_pointer node_pointer;
+ typedef typename Allocators::size_type size_type;
public:
inline insert(node_pointer & root,
- size_t & leafs_level,
+ size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
- size_t relative_level = 0)
+ size_type relative_level = 0)
: m_root(root), m_leafs_level(leafs_level), m_element(element)
, m_parameters(parameters), m_translator(translator)
, m_relative_level(relative_level), m_allocators(allocators)
{}
- inline void operator()(internal_node & BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(n))
+ inline void operator()(internal_node & n)
{
+ boost::ignore_unused(n);
BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<internal_node>(*m_root), "current node should be the root");
// Distinguish between situation when reinserts are required and use adequate visitor, otherwise use default one
@@ -493,8 +499,9 @@ public:
}
}
- inline void operator()(leaf & BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(n))
+ inline void operator()(leaf & n)
{
+ boost::ignore_unused(n);
BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<leaf>(*m_root), "current node should be the root");
// Distinguish between situation when reinserts are required and use adequate visitor, otherwise use default one
@@ -554,13 +561,13 @@ private:
}
node_pointer & m_root;
- size_t & m_leafs_level;
+ size_type & m_leafs_level;
Element const& m_element;
parameters_type const& m_parameters;
Translator const& m_translator;
- size_t m_relative_level;
+ size_type m_relative_level;
Allocators & m_allocators;
};
diff --git a/3party/boost/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp b/3party/boost/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp
index 0caf53f94e..8f270537fb 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp
@@ -89,13 +89,13 @@ private:
Translator const& m_tr;
};
-template <typename Parameters, typename Box, size_t Corner, size_t AxisIndex>
+template <typename Box, size_t Corner, size_t AxisIndex>
struct choose_split_axis_and_index_for_corner
{
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
- template <typename Elements, typename Translator>
+ template <typename Elements, typename Parameters, typename Translator>
static inline void apply(Elements const& elements,
size_t & choosen_index,
margin_type & sum_of_margins,
@@ -113,19 +113,28 @@ struct choose_split_axis_and_index_for_corner
// copy elements
Elements elements_copy(elements); // MAY THROW, STRONG (alloc, copy)
+ size_t const index_first = parameters.get_min_elements();
+ size_t const index_last = parameters.get_max_elements() - parameters.get_min_elements() + 2;
+
// sort elements
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, AxisIndex> elements_less(translator);
std::sort(elements_copy.begin(), elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
+// {
+// typename Elements::iterator f = elements_copy.begin() + index_first;
+// typename Elements::iterator l = elements_copy.begin() + index_last;
+// std::nth_element(elements_copy.begin(), f, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
+// std::nth_element(f, l, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
+// std::sort(f, l, elements_less); // MAY THROW, BASIC (copy)
+// }
// init outputs
- choosen_index = parameters.get_min_elements();
+ choosen_index = index_first;
sum_of_margins = 0;
smallest_overlap = (std::numeric_limits<content_type>::max)();
smallest_content = (std::numeric_limits<content_type>::max)();
// calculate sum of margins for all distributions
- size_t index_last = parameters.get_max_elements() - parameters.get_min_elements() + 2;
- for ( size_t i = parameters.get_min_elements() ; i < index_last ; ++i )
+ for ( size_t i = index_first ; i < index_last ; ++i )
{
// TODO - awulkiew: may be optimized - box of group 1 may be initialized with
// box of min_elems number of elements and expanded for each iteration by another element
@@ -151,19 +160,19 @@ struct choose_split_axis_and_index_for_corner
}
};
-//template <typename Parameters, typename Box, size_t AxisIndex, typename ElementIndexableTag>
+//template <typename Box, size_t AxisIndex, typename ElementIndexableTag>
//struct choose_split_axis_and_index_for_axis
//{
// BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag));
//};
-template <typename Parameters, typename Box, size_t AxisIndex, typename ElementIndexableTag>
+template <typename Box, size_t AxisIndex, typename ElementIndexableTag>
struct choose_split_axis_and_index_for_axis
{
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
- template <typename Elements, typename Translator>
+ template <typename Elements, typename Parameters, typename Translator>
static inline void apply(Elements const& elements,
size_t & choosen_corner,
size_t & choosen_index,
@@ -178,20 +187,20 @@ struct choose_split_axis_and_index_for_axis
content_type ovl1 = (std::numeric_limits<content_type>::max)();
content_type con1 = (std::numeric_limits<content_type>::max)();
- choose_split_axis_and_index_for_corner<Parameters, Box, min_corner, AxisIndex>::
- apply(elements, index1,
- som1, ovl1, con1,
- parameters, translator); // MAY THROW, STRONG
+ choose_split_axis_and_index_for_corner<Box, min_corner, AxisIndex>
+ ::apply(elements, index1,
+ som1, ovl1, con1,
+ parameters, translator); // MAY THROW, STRONG
size_t index2 = 0;
margin_type som2 = 0;
content_type ovl2 = (std::numeric_limits<content_type>::max)();
content_type con2 = (std::numeric_limits<content_type>::max)();
- choose_split_axis_and_index_for_corner<Parameters, Box, max_corner, AxisIndex>::
- apply(elements, index2,
- som2, ovl2, con2,
- parameters, translator); // MAY THROW, STRONG
+ choose_split_axis_and_index_for_corner<Box, max_corner, AxisIndex>
+ ::apply(elements, index2,
+ som2, ovl2, con2,
+ parameters, translator); // MAY THROW, STRONG
sum_of_margins = som1 + som2;
@@ -212,13 +221,13 @@ struct choose_split_axis_and_index_for_axis
}
};
-template <typename Parameters, typename Box, size_t AxisIndex>
-struct choose_split_axis_and_index_for_axis<Parameters, Box, AxisIndex, point_tag>
+template <typename Box, size_t AxisIndex>
+struct choose_split_axis_and_index_for_axis<Box, AxisIndex, point_tag>
{
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
- template <typename Elements, typename Translator>
+ template <typename Elements, typename Parameters, typename Translator>
static inline void apply(Elements const& elements,
size_t & choosen_corner,
size_t & choosen_index,
@@ -228,16 +237,16 @@ struct choose_split_axis_and_index_for_axis<Parameters, Box, AxisIndex, point_ta
Parameters const& parameters,
Translator const& translator)
{
- choose_split_axis_and_index_for_corner<Parameters, Box, min_corner, AxisIndex>::
- apply(elements, choosen_index,
- sum_of_margins, smallest_overlap, smallest_content,
- parameters, translator); // MAY THROW, STRONG
+ choose_split_axis_and_index_for_corner<Box, min_corner, AxisIndex>
+ ::apply(elements, choosen_index,
+ sum_of_margins, smallest_overlap, smallest_content,
+ parameters, translator); // MAY THROW, STRONG
choosen_corner = min_corner;
}
};
-template <typename Parameters, typename Box, size_t Dimension>
+template <typename Box, size_t Dimension>
struct choose_split_axis_and_index
{
BOOST_STATIC_ASSERT(0 < Dimension);
@@ -245,7 +254,7 @@ struct choose_split_axis_and_index
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
- template <typename Elements, typename Translator>
+ template <typename Elements, typename Parameters, typename Translator>
static inline void apply(Elements const& elements,
size_t & choosen_axis,
size_t & choosen_corner,
@@ -258,10 +267,10 @@ struct choose_split_axis_and_index
{
typedef typename rtree::element_indexable_type<typename Elements::value_type, Translator>::type element_indexable_type;
- choose_split_axis_and_index<Parameters, Box, Dimension - 1>::
- apply(elements, choosen_axis, choosen_corner, choosen_index,
- smallest_sum_of_margins, smallest_overlap, smallest_content,
- parameters, translator); // MAY THROW, STRONG
+ choose_split_axis_and_index<Box, Dimension - 1>
+ ::apply(elements, choosen_axis, choosen_corner, choosen_index,
+ smallest_sum_of_margins, smallest_overlap, smallest_content,
+ parameters, translator); // MAY THROW, STRONG
margin_type sum_of_margins = 0;
@@ -272,7 +281,6 @@ struct choose_split_axis_and_index
content_type content_val = (std::numeric_limits<content_type>::max)();
choose_split_axis_and_index_for_axis<
- Parameters,
Box,
Dimension - 1,
typename tag<element_indexable_type>::type
@@ -290,13 +298,13 @@ struct choose_split_axis_and_index
}
};
-template <typename Parameters, typename Box>
-struct choose_split_axis_and_index<Parameters, Box, 1>
+template <typename Box>
+struct choose_split_axis_and_index<Box, 1>
{
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
- template <typename Elements, typename Translator>
+ template <typename Elements, typename Parameters, typename Translator>
static inline void apply(Elements const& elements,
size_t & choosen_axis,
size_t & choosen_corner,
@@ -312,7 +320,6 @@ struct choose_split_axis_and_index<Parameters, Box, 1>
choosen_axis = 0;
choose_split_axis_and_index_for_axis<
- Parameters,
Box,
0,
typename tag<element_indexable_type>::type
@@ -320,50 +327,39 @@ struct choose_split_axis_and_index<Parameters, Box, 1>
}
};
-template <size_t Corner, size_t Dimension>
-struct partial_sort
+template <size_t Corner, size_t Dimension, size_t I = 0>
+struct nth_element
{
BOOST_STATIC_ASSERT(0 < Dimension);
+ BOOST_STATIC_ASSERT(I < Dimension);
template <typename Elements, typename Translator>
static inline void apply(Elements & elements, const size_t axis, const size_t index, Translator const& tr)
{
- if ( axis < Dimension - 1 )
+ //BOOST_GEOMETRY_INDEX_ASSERT(axis < Dimension, "unexpected axis value");
+
+ if ( axis != I )
{
- partial_sort<Corner, Dimension - 1>::apply(elements, axis, index, tr); // MAY THROW, BASIC (copy)
+ nth_element<Corner, Dimension, I + 1>::apply(elements, axis, index, tr); // MAY THROW, BASIC (copy)
}
else
{
- BOOST_GEOMETRY_INDEX_ASSERT(axis == Dimension - 1, "unexpected axis value");
-
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename tag<indexable_type>::type indexable_tag;
- element_axis_corner_less<element_type, Translator, indexable_tag, Corner, Dimension - 1> less(tr);
- std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
+ element_axis_corner_less<element_type, Translator, indexable_tag, Corner, I> less(tr);
+ std::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
}
}
};
-template <size_t Corner>
-struct partial_sort<Corner, 1>
+template <size_t Corner, size_t Dimension>
+struct nth_element<Corner, Dimension, Dimension>
{
template <typename Elements, typename Translator>
- static inline void apply(Elements & elements,
- const size_t BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(axis),
- const size_t index,
- Translator const& tr)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(axis == 0, "unexpected axis value");
-
- typedef typename Elements::value_type element_type;
- typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename tag<indexable_type>::type indexable_tag;
-
- element_axis_corner_less<element_type, Translator, indexable_tag, Corner, 0> less(tr);
- std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
- }
+ static inline void apply(Elements & /*elements*/, const size_t /*axis*/, const size_t /*index*/, Translator const& /*tr*/)
+ {}
};
} // namespace rstar
@@ -393,14 +389,17 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
Allocators & allocators)
{
typedef typename rtree::elements_type<Node>::type elements_type;
+ typedef typename elements_type::value_type element_type;
elements_type & elements1 = rtree::elements(n);
elements_type & elements2 = rtree::elements(second_node);
- // copy original elements
- // TODO: use container_from_elements_type for std::allocator
- elements_type elements_copy(elements1); // MAY THROW, STRONG
- elements_type elements_backup(elements1); // MAY THROW, STRONG
+ // copy original elements - use in-memory storage (std::allocator)
+ // TODO: move if noexcept
+ typedef typename rtree::container_from_elements_type<elements_type, element_type>::type
+ container_type;
+ container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG
+ container_type elements_backup(elements1.begin(), elements1.end()); // MAY THROW, STRONG
size_t split_axis = 0;
size_t split_corner = 0;
@@ -414,14 +413,11 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
// and again, the same below calling partial_sort/nth_element
// It would be even possible to not re-sort/find nth_element if the axis/corner
// was found for the last sorting - last combination of axis/corner
- rstar::choose_split_axis_and_index<
- typename Options::parameters_type,
- Box,
- dimension
- >::apply(elements_copy,
- split_axis, split_corner, split_index,
- smallest_sum_of_margins, smallest_overlap, smallest_content,
- parameters, translator); // MAY THROW, STRONG
+ rstar::choose_split_axis_and_index<Box, dimension>
+ ::apply(elements_copy,
+ split_axis, split_corner, split_index,
+ smallest_sum_of_margins, smallest_overlap, smallest_content,
+ parameters, translator); // MAY THROW, STRONG
// TODO: awulkiew - get rid of following static_casts?
BOOST_GEOMETRY_INDEX_ASSERT(split_axis < dimension, "unexpected value");
@@ -431,12 +427,12 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
// TODO: consider using nth_element
if ( split_corner == static_cast<size_t>(min_corner) )
{
- rstar::partial_sort<min_corner, dimension>
+ rstar::nth_element<min_corner, dimension>
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
}
else
{
- rstar::partial_sort<max_corner, dimension>
+ rstar::nth_element<max_corner, dimension>
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
}
diff --git a/3party/boost/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp b/3party/boost/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp
new file mode 100644
index 0000000000..10a1bec6ad
--- /dev/null
+++ b/3party/boost/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp
@@ -0,0 +1,110 @@
+// Boost.Geometry Index
+//
+// R-tree nodes elements numbers validating visitor implementation
+//
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP
+
+#include <boost/geometry/index/detail/rtree/node/node.hpp>
+
+namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
+
+namespace visitors {
+
+template <typename Value, typename Options, typename Box, typename Allocators>
+class are_counts_ok
+ : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
+{
+ typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
+ typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
+ typedef typename Options::parameters_type parameters_type;
+
+public:
+ inline are_counts_ok(parameters_type const& parameters)
+ : result(true), m_current_level(0), m_parameters(parameters)
+ {}
+
+ inline void operator()(internal_node const& n)
+ {
+ typedef typename rtree::elements_type<internal_node>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ // root internal node shouldn't contain 0 elements
+ if ( elements.empty()
+ || !check_count(elements) )
+ {
+ result = false;
+ return;
+ }
+
+ size_t current_level_backup = m_current_level;
+ ++m_current_level;
+
+ for ( typename elements_type::const_iterator it = elements.begin();
+ it != elements.end() && result == true ;
+ ++it)
+ {
+ rtree::apply_visitor(*this, *it->second);
+ }
+
+ m_current_level = current_level_backup;
+ }
+
+ inline void operator()(leaf const& n)
+ {
+ typedef typename rtree::elements_type<leaf>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ // empty leaf in non-root node
+ if ( ( m_current_level > 0 && elements.empty() )
+ || !check_count(elements) )
+ {
+ result = false;
+ }
+ }
+
+ bool result;
+
+private:
+ template <typename Elements>
+ bool check_count(Elements const& elements)
+ {
+ // root may contain count < min but should never contain count > max
+ return elements.size() <= m_parameters.get_max_elements()
+ && ( elements.size() >= m_parameters.get_min_elements()
+ || m_current_level == 0 );
+ }
+
+ size_t m_current_level;
+ parameters_type const& m_parameters;
+};
+
+} // namespace visitors
+
+template <typename Rtree> inline
+bool are_counts_ok(Rtree const& tree)
+{
+ typedef utilities::view<Rtree> RTV;
+ RTV rtv(tree);
+
+ visitors::are_counts_ok<
+ typename RTV::value_type,
+ typename RTV::options_type,
+ typename RTV::box_type,
+ typename RTV::allocators_type
+ > v(tree.parameters());
+
+ rtv.apply_visitor(v);
+
+ return v.result;
+}
+
+}}}}}} // namespace boost::geometry::index::detail::rtree::utilities
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/visitors/copy.hpp b/3party/boost/boost/geometry/index/detail/rtree/visitors/copy.hpp
index 8fc25ac803..86ffc99caf 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/visitors/copy.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/visitors/copy.hpp
@@ -2,7 +2,7 @@
//
// R-tree deep copying visitor implementation
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -24,7 +24,7 @@ public:
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
- typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
+ typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
explicit inline copy(Allocators & allocators)
@@ -35,7 +35,7 @@ public:
inline void operator()(internal_node & n)
{
node_pointer raw_new_node = rtree::create_node<Allocators, internal_node>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
- node_auto_ptr new_node(raw_new_node, m_allocators);
+ subtree_destroyer new_node(raw_new_node, m_allocators);
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type & elements = rtree::elements(n);
@@ -48,7 +48,7 @@ public:
rtree::apply_visitor(*this, *it->second); // MAY THROW (V, E: alloc, copy, N: alloc)
// for exception safety
- node_auto_ptr auto_result(result, m_allocators);
+ subtree_destroyer auto_result(result, m_allocators);
elements_dst.push_back( rtree::make_ptr_pair(it->first, result) ); // MAY THROW, STRONG (E: alloc, copy)
@@ -62,7 +62,7 @@ public:
inline void operator()(leaf & l)
{
node_pointer raw_new_node = rtree::create_node<Allocators, leaf>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
- node_auto_ptr new_node(raw_new_node, m_allocators);
+ subtree_destroyer new_node(raw_new_node, m_allocators);
typedef typename rtree::elements_type<leaf>::type elements_type;
elements_type & elements = rtree::elements(l);
diff --git a/3party/boost/boost/geometry/index/detail/rtree/visitors/count.hpp b/3party/boost/boost/geometry/index/detail/rtree/visitors/count.hpp
index f521944a44..7efd5b7028 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/visitors/count.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/visitors/count.hpp
@@ -15,68 +15,48 @@ namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
-template <typename Indexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
-struct count
- : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
+template <typename Indexable, typename Value>
+struct count_helper
{
- typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
- typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
- typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
-
- inline count(Indexable const& i, Translator const& t)
- : indexable(i), tr(t), found_count(0)
- {}
-
- inline void operator()(internal_node const& n)
+ template <typename Translator>
+ static inline typename Translator::result_type indexable(Indexable const& i, Translator const&)
{
- typedef typename rtree::elements_type<internal_node>::type elements_type;
- elements_type const& elements = rtree::elements(n);
-
- // traverse nodes meeting predicates
- for (typename elements_type::const_iterator it = elements.begin();
- it != elements.end(); ++it)
- {
- if ( geometry::covered_by(
- return_ref_or_bounds(indexable),
- it->first) )
- {
- rtree::apply_visitor(*this, *it->second);
- }
- }
+ return i;
}
-
- inline void operator()(leaf const& n)
+ template <typename Translator>
+ static inline bool equals(Indexable const& i, Value const& v, Translator const& tr)
{
- typedef typename rtree::elements_type<leaf>::type elements_type;
- elements_type const& elements = rtree::elements(n);
-
- // get all values meeting predicates
- for (typename elements_type::const_iterator it = elements.begin();
- it != elements.end(); ++it)
- {
- // if value meets predicates
- if ( geometry::equals(indexable, tr(*it)) )
- {
- ++found_count;
- }
- }
+ return geometry::equals(i, tr(v));
}
+};
- Indexable const& indexable;
- Translator const& tr;
- typename Allocators::size_type found_count;
+template <typename Value>
+struct count_helper<Value, Value>
+{
+ template <typename Translator>
+ static inline typename Translator::result_type indexable(Value const& v, Translator const& tr)
+ {
+ return tr(v);
+ }
+ template <typename Translator>
+ static inline bool equals(Value const& v1, Value const& v2, Translator const& tr)
+ {
+ return tr.equals(v1, v2);
+ }
};
-template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
-struct count<Value, Value, Options, Translator, Box, Allocators>
+template <typename ValueOrIndexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+struct count
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
- inline count(Value const& v, Translator const& t)
- : value(v), tr(t), found_count(0)
+ typedef count_helper<ValueOrIndexable, Value> count_help;
+
+ inline count(ValueOrIndexable const& vori, Translator const& t)
+ : value_or_indexable(vori), tr(t), found_count(0)
{}
inline void operator()(internal_node const& n)
@@ -89,7 +69,8 @@ struct count<Value, Value, Options, Translator, Box, Allocators>
it != elements.end(); ++it)
{
if ( geometry::covered_by(
- return_ref_or_bounds(tr(value)),
+ return_ref_or_bounds(
+ count_help::indexable(value_or_indexable, tr)),
it->first) )
{
rtree::apply_visitor(*this, *it->second);
@@ -107,14 +88,14 @@ struct count<Value, Value, Options, Translator, Box, Allocators>
it != elements.end(); ++it)
{
// if value meets predicates
- if ( tr.equals(value, *it) )
+ if ( count_help::equals(value_or_indexable, *it, tr) )
{
++found_count;
}
}
}
- Value const& value;
+ ValueOrIndexable const& value_or_indexable;
Translator const& tr;
typename Allocators::size_type found_count;
};
diff --git a/3party/boost/boost/geometry/index/detail/rtree/visitors/destroy.hpp b/3party/boost/boost/geometry/index/detail/rtree/visitors/destroy.hpp
index 62722b97a8..b4a800eac2 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/visitors/destroy.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/visitors/destroy.hpp
@@ -2,7 +2,7 @@
//
// R-tree destroying visitor implementation
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -51,8 +51,9 @@ public:
rtree::destroy_node<Allocators, internal_node>::apply(m_allocators, node_to_destroy);
}
- inline void operator()(leaf & BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(l))
+ inline void operator()(leaf & l)
{
+ boost::ignore_unused(l);
BOOST_GEOMETRY_INDEX_ASSERT(&l == &rtree::get<leaf>(*m_current_node), "invalid pointers");
rtree::destroy_node<Allocators, leaf>::apply(m_allocators, m_current_node);
diff --git a/3party/boost/boost/geometry/index/detail/rtree/visitors/distance_query.hpp b/3party/boost/boost/geometry/index/detail/rtree/visitors/distance_query.hpp
index c0d336df1a..b930714433 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/visitors/distance_query.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/visitors/distance_query.hpp
@@ -2,7 +2,7 @@
//
// R-tree distance (knn, path, etc. ) query visitor implementation
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -187,6 +187,33 @@ public:
rtree::apply_visitor(*this, *(it->second));
}
+
+ // ALTERNATIVE VERSION - use heap instead of sorted container
+ // It seems to be faster for greater MaxElements and slower otherwise
+ // CONSIDER: using one global container/heap for active branches
+ // instead of a sorted container per level
+ // This would also change the way how branches are traversed!
+ // The same may be applied to the iterative version which btw suffers
+ // from the copying of the whole containers on resize of the ABLs container
+
+ //// make a heap
+ //std::make_heap(active_branch_list.begin(), active_branch_list.end(), abl_greater);
+
+ //// recursively visit nodes
+ //while ( !active_branch_list.empty() )
+ //{
+ // //if current node is further than furthest neighbor, the rest of nodes also will be further
+ // if ( m_result.has_enough_neighbors()
+ // && is_node_prunable(m_result.greatest_comparable_distance(), active_branch_list.front().first) )
+ // {
+ // break;
+ // }
+
+ // rtree::apply_visitor(*this, *(active_branch_list.front().second));
+
+ // std::pop_heap(active_branch_list.begin(), active_branch_list.end(), abl_greater);
+ // active_branch_list.pop_back();
+ //}
}
inline void operator()(leaf const& n)
@@ -226,6 +253,13 @@ private:
return p1.first < p2.first;
}
+ //static inline bool abl_greater(
+ // std::pair<node_distance_type, typename Allocators::node_pointer> const& p1,
+ // std::pair<node_distance_type, typename Allocators::node_pointer> const& p2)
+ //{
+ // return p1.first > p2.first;
+ //}
+
template <typename Distance>
static inline bool is_node_prunable(Distance const& greatest_dist, node_distance_type const& d)
{
@@ -303,6 +337,13 @@ public:
};
typedef std::vector<internal_stack_element> internal_stack_type;
+ inline distance_query_incremental()
+ : m_translator(NULL)
+// , m_pred()
+ , current_neighbor((std::numeric_limits<size_type>::max)())
+// , next_closest_node_distance((std::numeric_limits<node_distance_type>::max)())
+ {}
+
inline distance_query_incremental(Translator const& translator, Predicates const& pred)
: m_translator(::boost::addressof(translator))
, m_pred(pred)
@@ -310,7 +351,7 @@ public:
, next_closest_node_distance((std::numeric_limits<node_distance_type>::max)())
{
- BOOST_ASSERT_MSG(0 < max_count(), "k must be greather than 0");
+ BOOST_GEOMETRY_INDEX_ASSERT(0 < max_count(), "k must be greather than 0");
}
const_reference dereference() const
@@ -365,7 +406,7 @@ public:
}
// if node is further than the furthest neighbour, following nodes also will be further
- BOOST_ASSERT_MSG(neighbors.size() <= max_count(), "unexpected neighbours count");
+ BOOST_GEOMETRY_INDEX_ASSERT(neighbors.size() <= max_count(), "unexpected neighbours count");
if ( max_count() <= neighbors.size() &&
is_node_prunable(neighbors.back().first, branches[current_branch].first) )
{
@@ -392,10 +433,11 @@ public:
friend bool operator==(distance_query_incremental const& l, distance_query_incremental const& r)
{
- BOOST_ASSERT_MSG(l.current_neighbor != r.current_neighbor ||
- (std::numeric_limits<size_type>::max)() == l.current_neighbor ||
- l.neighbors[l.current_neighbor].second == r.neighbors[r.current_neighbor].second,
- "not corresponding iterators");
+ BOOST_GEOMETRY_INDEX_ASSERT(l.current_neighbor != r.current_neighbor ||
+ (std::numeric_limits<size_type>::max)() == l.current_neighbor ||
+ (std::numeric_limits<size_type>::max)() == r.current_neighbor ||
+ l.neighbors[l.current_neighbor].second == r.neighbors[r.current_neighbor].second,
+ "not corresponding iterators");
return l.current_neighbor == r.current_neighbor;
}
diff --git a/3party/boost/boost/geometry/index/detail/rtree/visitors/insert.hpp b/3party/boost/boost/geometry/index/detail/rtree/visitors/insert.hpp
index a5c16db8af..e697c065e1 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/visitors/insert.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/visitors/insert.hpp
@@ -2,7 +2,7 @@
//
// R-tree inserting visitor implementation
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -115,7 +115,7 @@ protected:
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
- typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
+ typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
public:
typedef index::detail::varray<
@@ -133,8 +133,8 @@ public:
{
// TODO - consider creating nodes always with sufficient memory allocated
- // create additional node, use auto ptr for automatic destruction on exception
- node_auto_ptr second_node(rtree::create_node<Allocators, Node>::apply(allocators), allocators); // MAY THROW, STRONG (N: alloc)
+ // create additional node, use auto destroyer for automatic destruction on exception
+ subtree_destroyer second_node(rtree::create_node<Allocators, Node>::apply(allocators), allocators); // MAY THROW, STRONG (N: alloc)
// create reference to the newly created node
Node & n2 = rtree::get<Node>(*second_node);
@@ -178,17 +178,20 @@ public:
namespace visitors { namespace detail {
-template <typename InternalNode, typename InternalNodePtr>
+template <typename InternalNode, typename InternalNodePtr, typename SizeType>
struct insert_traverse_data
{
typedef typename rtree::elements_type<InternalNode>::type elements_type;
typedef typename elements_type::value_type element_type;
+ typedef typename elements_type::size_type elements_size_type;
+ typedef SizeType size_type;
insert_traverse_data()
: parent(0), current_child_index(0), current_level(0)
{}
- void move_to_next_level(InternalNodePtr new_parent, size_t new_child_index)
+ void move_to_next_level(InternalNodePtr new_parent,
+ elements_size_type new_child_index)
{
parent = new_parent;
current_child_index = new_child_index;
@@ -213,8 +216,8 @@ struct insert_traverse_data
}
InternalNodePtr parent;
- size_t current_child_index;
- size_t current_level;
+ elements_size_type current_child_index;
+ size_type current_level;
};
// Default insert visitor
@@ -229,19 +232,20 @@ protected:
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
- typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
+ typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
+ typedef typename Allocators::size_type size_type;
//typedef typename Allocators::internal_node_pointer internal_node_pointer;
typedef internal_node * internal_node_pointer;
inline insert(node_pointer & root,
- size_t & leafs_level,
+ size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
- size_t relative_level = 0
+ size_type relative_level = 0
)
: m_element(element)
, m_parameters(parameters)
@@ -298,7 +302,8 @@ protected:
inline void traverse_apply_visitor(Visitor & visitor, internal_node &n, size_t choosen_node_index)
{
// save previous traverse inputs and set new ones
- insert_traverse_data<internal_node, internal_node_pointer> backup_traverse_data = m_traverse_data;
+ insert_traverse_data<internal_node, internal_node_pointer, size_type>
+ backup_traverse_data = m_traverse_data;
// calculate new traverse inputs
m_traverse_data.move_to_next_level(&n, choosen_node_index);
@@ -335,7 +340,7 @@ protected:
// Implement template <node_tag> struct node_element_type or something like that
// for exception safety
- node_auto_ptr additional_node_ptr(additional_nodes[0].second, m_allocators);
+ subtree_destroyer additional_node_ptr(additional_nodes[0].second, m_allocators);
// node is not the root - just add the new node
if ( !m_traverse_data.current_is_root() )
@@ -351,7 +356,7 @@ protected:
BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<Node>(*m_root_node), "node should be the root");
// create new root and add nodes
- node_auto_ptr new_root(rtree::create_node<Allocators, internal_node>::apply(m_allocators), m_allocators); // MAY THROW, STRONG (N:alloc)
+ subtree_destroyer new_root(rtree::create_node<Allocators, internal_node>::apply(m_allocators), m_allocators); // MAY THROW, STRONG (N:alloc)
BOOST_TRY
{
@@ -360,7 +365,7 @@ protected:
}
BOOST_CATCH(...)
{
- // clear new root to not delete in the ~node_auto_ptr() potentially stored old root node
+ // clear new root to not delete in the ~subtree_destroyer() potentially stored old root node
rtree::elements(rtree::get<internal_node>(*new_root)).clear();
BOOST_RETHROW // RETHROW
}
@@ -380,14 +385,14 @@ protected:
Element const& m_element;
parameters_type const& m_parameters;
Translator const& m_translator;
- const size_t m_relative_level;
- const size_t m_level;
+ size_type const m_relative_level;
+ size_type const m_level;
node_pointer & m_root_node;
- size_t & m_leafs_level;
+ size_type & m_leafs_level;
// traversing input parameters
- insert_traverse_data<internal_node, internal_node_pointer> m_traverse_data;
+ insert_traverse_data<internal_node, internal_node_pointer, size_type> m_traverse_data;
Allocators & m_allocators;
};
@@ -414,14 +419,15 @@ public:
typedef typename Options::parameters_type parameters_type;
typedef typename base::node_pointer node_pointer;
+ typedef typename base::size_type size_type;
inline insert(node_pointer & root,
- size_t & leafs_level,
+ size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
- size_t relative_level = 0
+ size_type relative_level = 0
)
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
{}
@@ -478,14 +484,15 @@ public:
typedef typename Options::parameters_type parameters_type;
typedef typename base::node_pointer node_pointer;
+ typedef typename base::size_type size_type;
inline insert(node_pointer & root,
- size_t & leafs_level,
+ size_type & leafs_level,
Value const& value,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
- size_t relative_level = 0
+ size_type relative_level = 0
)
: base(root, leafs_level, value, parameters, translator, allocators, relative_level)
{}
diff --git a/3party/boost/boost/geometry/index/detail/rtree/visitors/is_leaf.hpp b/3party/boost/boost/geometry/index/detail/rtree/visitors/is_leaf.hpp
index 6d21afd99e..dd2159c71e 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/visitors/is_leaf.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/visitors/is_leaf.hpp
@@ -2,7 +2,7 @@
//
// R-tree leaf node checking visitor implementation
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -21,9 +21,13 @@ struct is_leaf : public rtree::visitor<Value, typename Options::parameters_type,
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
+ is_leaf()
+ : result(false)
+ {}
+
inline void operator()(internal_node const&)
{
- result = false;
+ // result = false;
}
inline void operator()(leaf const&)
diff --git a/3party/boost/boost/geometry/index/detail/rtree/visitors/iterator.hpp b/3party/boost/boost/geometry/index/detail/rtree/visitors/iterator.hpp
new file mode 100644
index 0000000000..621231ae9a
--- /dev/null
+++ b/3party/boost/boost/geometry/index/detail/rtree/visitors/iterator.hpp
@@ -0,0 +1,134 @@
+// Boost.Geometry Index
+//
+// R-tree iterator visitor implementation
+//
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree { namespace visitors {
+
+template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+class iterator
+ : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
+{
+public:
+ typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
+ typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
+ typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
+
+ typedef typename Allocators::size_type size_type;
+ typedef typename Allocators::const_reference const_reference;
+ typedef typename Allocators::node_pointer node_pointer;
+
+ typedef typename rtree::elements_type<internal_node>::type::const_iterator internal_iterator;
+ typedef typename rtree::elements_type<leaf>::type leaf_elements;
+ typedef typename rtree::elements_type<leaf>::type::const_iterator leaf_iterator;
+
+ inline iterator()
+ : m_values(NULL)
+ , m_current()
+ {}
+
+ inline void operator()(internal_node const& n)
+ {
+ typedef typename rtree::elements_type<internal_node>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ m_internal_stack.push_back(std::make_pair(elements.begin(), elements.end()));
+ }
+
+ inline void operator()(leaf const& n)
+ {
+ m_values = ::boost::addressof(rtree::elements(n));
+ m_current = rtree::elements(n).begin();
+ }
+
+ const_reference dereference() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(m_values, "not dereferencable");
+ return *m_current;
+ }
+
+ void initialize(node_pointer root)
+ {
+ rtree::apply_visitor(*this, *root);
+ search_value();
+ }
+
+ void increment()
+ {
+ ++m_current;
+ search_value();
+ }
+
+ void search_value()
+ {
+ for (;;)
+ {
+ // if leaf is choosen, move to the next value in leaf
+ if ( m_values )
+ {
+ // there are more values in the current leaf
+ if ( m_current != m_values->end() )
+ {
+ return;
+ }
+ // no more values, clear current leaf
+ else
+ {
+ m_values = 0;
+ }
+ }
+ // if leaf isn't choosen, move to the next leaf
+ else
+ {
+ // return if there is no more nodes to traverse
+ if ( m_internal_stack.empty() )
+ return;
+
+ // no more children in current node, remove it from stack
+ if ( m_internal_stack.back().first == m_internal_stack.back().second )
+ {
+ m_internal_stack.pop_back();
+ continue;
+ }
+
+ internal_iterator it = m_internal_stack.back().first;
+ ++m_internal_stack.back().first;
+
+ // push the next node to the stack
+ rtree::apply_visitor(*this, *(it->second));
+ }
+ }
+ }
+
+ bool is_end() const
+ {
+ return 0 == m_values;
+ }
+
+ friend bool operator==(iterator const& l, iterator const& r)
+ {
+ return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current );
+ }
+
+private:
+
+ std::vector< std::pair<internal_iterator, internal_iterator> > m_internal_stack;
+ const leaf_elements * m_values;
+ leaf_iterator m_current;
+};
+
+}}} // namespace detail::rtree::visitors
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
diff --git a/3party/boost/boost/geometry/index/detail/rtree/visitors/remove.hpp b/3party/boost/boost/geometry/index/detail/rtree/visitors/remove.hpp
index 8e6255346d..494d5a019e 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/visitors/remove.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/visitors/remove.hpp
@@ -2,7 +2,7 @@
//
// R-tree removing visitor implementation
//
-// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -30,15 +30,18 @@ class remove
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
- typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
+ typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
+ typedef typename Allocators::size_type size_type;
+
+ typedef typename rtree::elements_type<internal_node>::type::size_type internal_size_type;
//typedef typename Allocators::internal_node_pointer internal_node_pointer;
typedef internal_node * internal_node_pointer;
public:
inline remove(node_pointer & root,
- size_t & leafs_level,
+ size_type & leafs_level,
Value const& value,
parameters_type const& parameters,
Translator const& translator,
@@ -65,7 +68,7 @@ public:
children_type & children = rtree::elements(n);
// traverse children which boxes intersects value's box
- size_t child_node_index = 0;
+ internal_size_type child_node_index = 0;
for ( ; child_node_index < children.size() ; ++child_node_index )
{
if ( geometry::covered_by(
@@ -91,7 +94,7 @@ public:
if ( m_is_underflow )
{
element_iterator underfl_el_it = elements.begin() + child_node_index;
- size_t relative_level = m_leafs_level - m_current_level;
+ size_type relative_level = m_leafs_level - m_current_level;
// move node to the container - store node's relative level as well and return new underflow state
m_is_underflow = store_underflowed_node(elements, underfl_el_it, relative_level); // MAY THROW (E: alloc, copy)
@@ -149,7 +152,7 @@ public:
// if value was removed
if ( m_is_value_removed )
{
- BOOST_ASSERT_MSG(0 < m_parameters.get_min_elements(), "min number of elements is too small");
+ BOOST_GEOMETRY_INDEX_ASSERT(0 < m_parameters.get_min_elements(), "min number of elements is too small");
// calc underflow
m_is_underflow = elements.size() < m_parameters.get_min_elements();
@@ -170,14 +173,14 @@ public:
private:
- typedef std::vector< std::pair<size_t, node_pointer> > UnderflowNodes;
+ typedef std::vector< std::pair<size_type, node_pointer> > UnderflowNodes;
- void traverse_apply_visitor(internal_node &n, size_t choosen_node_index)
+ void traverse_apply_visitor(internal_node &n, internal_size_type choosen_node_index)
{
// save previous traverse inputs and set new ones
internal_node_pointer parent_bckup = m_parent;
- size_t current_child_index_bckup = m_current_child_index;
- size_t current_level_bckup = m_current_level;
+ internal_size_type current_child_index_bckup = m_current_child_index;
+ size_type current_level_bckup = m_current_level;
m_parent = &n;
m_current_child_index = choosen_node_index;
@@ -195,7 +198,7 @@ private:
bool store_underflowed_node(
typename rtree::elements_type<internal_node>::type & elements,
typename rtree::elements_type<internal_node>::type::iterator underfl_el_it,
- size_t relative_level)
+ size_type relative_level)
{
// move node to the container - store node's relative level as well
m_underflowed_nodes.push_back(std::make_pair(relative_level, underfl_el_it->second)); // MAY THROW (E: alloc, copy)
@@ -219,6 +222,13 @@ private:
return elements.size() < m_parameters.get_min_elements();
}
+ static inline bool is_leaf(node const& n)
+ {
+ visitors::is_leaf<Value, Options, Box, Allocators> ilv;
+ rtree::apply_visitor(ilv, n);
+ return ilv.result;
+ }
+
void reinsert_removed_nodes_elements()
{
typename UnderflowNodes::reverse_iterator it = m_underflowed_nodes.rbegin();
@@ -229,9 +239,11 @@ private:
// begin with levels closer to the root
for ( ; it != m_underflowed_nodes.rend() ; ++it )
{
- is_leaf<Value, Options, Box, Allocators> ilv;
- rtree::apply_visitor(ilv, *it->second);
- if ( ilv.result )
+ // it->first is an index of a level of a node, not children
+ // counted from the leafs level
+ bool const node_is_leaf = it->first == 1;
+ BOOST_GEOMETRY_INDEX_ASSERT(node_is_leaf == is_leaf(*it->second), "unexpected condition");
+ if ( node_is_leaf )
{
reinsert_node_elements(rtree::get<leaf>(*it->second), it->first); // MAY THROW (V, E: alloc, copy, N: alloc)
@@ -252,7 +264,7 @@ private:
// destroy current and remaining nodes
for ( ; it != m_underflowed_nodes.rend() ; ++it )
{
- node_auto_ptr dummy(it->second, m_allocators);
+ subtree_destroyer dummy(it->second, m_allocators);
}
//m_underflowed_nodes.clear();
@@ -263,7 +275,7 @@ private:
}
template <typename Node>
- void reinsert_node_elements(Node &n, size_t node_relative_level)
+ void reinsert_node_elements(Node &n, size_type node_relative_level)
{
typedef typename rtree::elements_type<Node>::type elements_type;
elements_type & elements = rtree::elements(n);
@@ -302,15 +314,15 @@ private:
Allocators & m_allocators;
node_pointer & m_root_node;
- size_t & m_leafs_level;
+ size_type & m_leafs_level;
bool m_is_value_removed;
UnderflowNodes m_underflowed_nodes;
// traversing input parameters
internal_node_pointer m_parent;
- size_t m_current_child_index;
- size_t m_current_level;
+ internal_size_type m_current_child_index;
+ size_type m_current_level;
// traversing output parameters
bool m_is_underflow;
diff --git a/3party/boost/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/3party/boost/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp
index 0a43111ac4..b9cd0ae2c0 100644
--- a/3party/boost/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp
+++ b/3party/boost/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp
@@ -2,7 +2,7 @@
//
// R-tree spatial query visitor implementation
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -94,10 +94,18 @@ public:
static const unsigned predicates_len = index::detail::predicates_length<Predicates>::value;
+ inline spatial_query_incremental()
+ : m_translator(NULL)
+// , m_pred()
+ , m_values(NULL)
+ , m_current()
+ {}
+
inline spatial_query_incremental(Translator const& t, Predicates const& p)
: m_translator(::boost::addressof(t))
, m_pred(p)
- , m_values(0)
+ , m_values(NULL)
+ , m_current()
{}
inline void operator()(internal_node const& n)
@@ -116,7 +124,7 @@ public:
const_reference dereference() const
{
- BOOST_ASSERT_MSG(m_values, "not dereferencable");
+ BOOST_GEOMETRY_INDEX_ASSERT(m_values, "not dereferencable");
return *m_current;
}
diff --git a/3party/boost/boost/geometry/index/detail/serialization.hpp b/3party/boost/boost/geometry/index/detail/serialization.hpp
index 4f3dc7c013..550a37565b 100644
--- a/3party/boost/boost/geometry/index/detail/serialization.hpp
+++ b/3party/boost/boost/geometry/index/detail/serialization.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -225,7 +225,7 @@ template<class Archive> void serialize(Archive &, boost::geometry::index::dynami
// TODO - move to index/detail/serialization.hpp or maybe geometry/serialization.hpp
namespace boost { namespace geometry { namespace index { namespace detail {
-template <typename P, size_t I = 0, size_t D = traits::dimension<P>::value>
+template <typename P, size_t I = 0, size_t D = geometry::dimension<P>::value>
struct serialize_point
{
template <typename Archive>
@@ -239,7 +239,7 @@ struct serialize_point
template <typename Archive>
static inline void load(Archive & ar, P & p, unsigned int version)
{
- typename traits::coordinate_type<P>::type c;
+ typename geometry::coordinate_type<P>::type c;
ar >> boost::serialization::make_nvp("c", c);
set<I>(p, c);
serialize_point<P, I+1, D>::load(ar, p, version);
@@ -303,7 +303,8 @@ public:
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
- // change to elements_type::size_type or size_type?
+ // CONSIDER: change to elements_type::size_type or size_type
+ // or use fixed-size type like uint32 or even uint16?
size_t s = elements.size();
m_archive << boost::serialization::make_nvp("s", s);
@@ -318,10 +319,11 @@ public:
inline void operator()(leaf const& l)
{
typedef typename rtree::elements_type<leaf>::type elements_type;
- typedef typename elements_type::size_type elements_size;
+ //typedef typename elements_type::size_type elements_size;
elements_type const& elements = rtree::elements(l);
- // change to elements_type::size_type or size_type?
+ // CONSIDER: change to elements_type::size_type or size_type
+ // or use fixed-size type like uint32 or even uint16?
size_t s = elements.size();
m_archive << boost::serialization::make_nvp("s", s);
@@ -351,7 +353,7 @@ class load
typedef typename Options::parameters_type parameters_type;
typedef typename Allocators::node_pointer node_pointer;
- typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
+ typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::size_type size_type;
public:
@@ -368,7 +370,12 @@ private:
{
//BOOST_GEOMETRY_INDEX_ASSERT(current_level <= leafs_level, "invalid parameter");
- // change to elements_type::size_type or size_type?
+ typedef typename rtree::elements_type<internal_node>::type elements_type;
+ typedef typename elements_type::value_type element_type;
+ //typedef typename elements_type::size_type elements_size;
+
+ // CONSIDER: change to elements_type::size_type or size_type
+ // or use fixed-size type like uint32 or even uint16?
size_t elements_count;
ar >> boost::serialization::make_nvp("s", elements_count);
@@ -378,12 +385,9 @@ private:
if ( current_level < leafs_level )
{
node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A)
- node_auto_ptr auto_remover(n, allocators);
+ subtree_destroyer auto_remover(n, allocators);
internal_node & in = rtree::get<internal_node>(*n);
- typedef typename rtree::elements_type<internal_node>::type elements_type;
- typedef typename elements_type::value_type element_type;
- typedef typename elements_type::size_type elements_size;
elements_type & elements = rtree::elements(in);
elements.reserve(elements_count); // MAY THROW (A)
@@ -404,7 +408,7 @@ private:
BOOST_GEOMETRY_INDEX_ASSERT(current_level == leafs_level, "unexpected value");
node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A)
- node_auto_ptr auto_remover(n, allocators);
+ subtree_destroyer auto_remover(n, allocators);
leaf & l = rtree::get<leaf>(*n);
typedef typename rtree::elements_type<leaf>::type elements_type;
@@ -533,7 +537,7 @@ void load(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsig
typedef typename options_type::parameters_type parameters_type;
typedef typename allocators_type::node_pointer node_pointer;
- typedef detail::rtree::node_auto_ptr<value_type, options_type, translator_type, box_type, allocators_type> node_auto_ptr;
+ typedef detail::rtree::subtree_destroyer<value_type, options_type, translator_type, box_type, allocators_type> subtree_destroyer;
view tree(rt);
@@ -550,7 +554,7 @@ void load(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsig
n = detail::rtree::load<value_type, options_type, translator_type, box_type, allocators_type>
::apply(ar, version, leafs_level, loaded_values_count, params, tree.members().translator(), tree.members().allocators()); // MAY THROW
- node_auto_ptr remover(n, tree.members().allocators());
+ subtree_destroyer remover(n, tree.members().allocators());
if ( loaded_values_count != values_count )
BOOST_THROW_EXCEPTION(std::runtime_error("unexpected number of values")); // TODO change exception type
remover.release();
@@ -560,7 +564,7 @@ void load(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsig
tree.members().values_count = values_count;
tree.members().leafs_level = leafs_level;
- node_auto_ptr remover(tree.members().root, tree.members().allocators());
+ subtree_destroyer remover(tree.members().root, tree.members().allocators());
tree.members().root = n;
}
diff --git a/3party/boost/boost/geometry/index/detail/varray.hpp b/3party/boost/boost/geometry/index/detail/varray.hpp
index a795b7c3f3..1b084aafdb 100644
--- a/3party/boost/boost/geometry/index/detail/varray.hpp
+++ b/3party/boost/boost/geometry/index/detail/varray.hpp
@@ -1,6 +1,6 @@
// Boost.Container varray
//
-// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2012-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2013 Andrew Hundt.
//
// Use, modification and distribution is subject to the Boost Software License,
@@ -13,7 +13,10 @@
// TODO - REMOVE/CHANGE
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-#include <boost/container/detail/preprocessor.hpp>
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
#include <boost/config.hpp>
#include <boost/swap.hpp>
@@ -32,12 +35,11 @@
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/geometry/index/detail/assert.hpp>
+#include <boost/geometry/index/detail/exception.hpp>
-#include <boost/geometry/index/detail/assert.hpp>
#include <boost/geometry/index/detail/varray_detail.hpp>
#include <boost/concept_check.hpp>
-#include <boost/throw_exception.hpp>
/*!
\defgroup varray_non_member varray non-member functions
@@ -79,12 +81,8 @@ struct checker
static inline void throw_out_of_bounds(Varray const& v, size_type i)
{
-//#ifndef BOOST_NO_EXCEPTIONS
if ( v.size() <= i )
- BOOST_THROW_EXCEPTION(std::out_of_range("index out of bounds"));
-//#else // BOOST_NO_EXCEPTIONS
-// BOOST_GEOMETRY_INDEX_ASSERT(i < v.size(), "index out of bounds");
-//#endif // BOOST_NO_EXCEPTIONS
+ throw_out_of_range("index out of bounds");
::boost::ignore_unused_variable_warning(v);
::boost::ignore_unused_variable_warning(i);
@@ -920,9 +918,9 @@ public:
difference_type n = std::distance(first, last);
//TODO - add invalid range check?
- //BOOST_ASSERT_MSG(0 <= n, "invalid range");
+ //BOOST_GEOMETRY_INDEX_ASSERT(0 <= n, "invalid range");
//TODO - add this->size() check?
- //BOOST_ASSERT_MSG(n <= this->size(), "invalid range");
+ //BOOST_GEOMETRY_INDEX_ASSERT(n <= this->size(), "invalid range");
sv::move(last, this->end(), first); // may throw
sv::destroy(this->end() - n, this->end());
@@ -984,7 +982,7 @@ public:
}
#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
-#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! @pre <tt>size() < capacity()</tt>
//!
//! @brief Inserts a Value constructed with
@@ -1065,27 +1063,23 @@ public:
return position;
}
-#else // BOOST_CONTAINER_PERFECT_FORWARDING || BOOST_CONTAINER_DOXYGEN_INVOKED
+#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_EMPLACE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ void emplace_back(BOOST_MOVE_UREF##N) \
{ \
typedef typename vt::disable_trivial_init dti; \
\
errh::check_capacity(*this, m_size + 1); /*may throw*/\
\
- namespace sv = varray_detail; \
- sv::construct(dti(), this->end() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
+ namespace sv = varray_detail; \
+ sv::construct(dti(), this->end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
++m_size; /*update end*/ \
} \
- //
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(iterator position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace(iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
{ \
typedef typename vt::disable_trivial_init dti; \
namespace sv = varray_detail; \
@@ -1095,7 +1089,7 @@ public:
\
if ( position == this->end() ) \
{ \
- sv::construct(dti(), position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
+ sv::construct(dti(), position BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
++m_size; /*update end*/ \
} \
else \
@@ -1104,24 +1098,24 @@ public:
/* TODO - should move be used only if it's nonthrowing? */ \
\
value_type & r = *(this->end() - 1); \
- sv::construct(dti(), this->end(), boost::move(r)); /*may throw*/\
+ sv::construct(dti(), this->end(), boost::move(r)); /*may throw*/\
++m_size; /*update end*/ \
sv::move_backward(position, this->end() - 2, this->end() - 1); /*may throw*/\
\
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage; \
value_type * val_p = static_cast<value_type *>(temp_storage.address()); \
- sv::construct(dti(), val_p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
+ sv::construct(dti(), val_p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
sv::scoped_destructor<value_type> d(val_p); \
sv::assign(position, ::boost::move(*val_p)); /*may throw*/\
} \
\
return position; \
} \
- //
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+
+ BOOST_MOVE_ITERATE_0TO9(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_EMPLACE)
+ #undef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_EMPLACE
-#endif // BOOST_CONTAINER_PERFECT_FORWARDING || BOOST_CONTAINER_DOXYGEN_INVOKED
+#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
//! @brief Removes all elements from the container.
@@ -1406,7 +1400,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_reverse_iterator rbegin() const { return reverse_iterator(this->end()); }
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(this->end()); }
//! @brief Returns const reverse iterator to the first element of the reversed container.
//!
@@ -1418,7 +1412,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_reverse_iterator crbegin() const { return reverse_iterator(this->end()); }
+ const_reverse_iterator crbegin() const { return const_reverse_iterator(this->end()); }
//! @brief Returns reverse iterator to the one after the last element of the reversed container.
//!
@@ -1442,7 +1436,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_reverse_iterator rend() const { return reverse_iterator(this->begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(this->begin()); }
//! @brief Returns const reverse iterator to the one after the last element of the reversed container.
//!
@@ -1454,7 +1448,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_reverse_iterator crend() const { return reverse_iterator(this->begin()); }
+ const_reverse_iterator crend() const { return const_reverse_iterator(this->begin()); }
//! @brief Returns container's capacity.
//!
@@ -1614,7 +1608,8 @@ private:
// Linear O(N).
void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::true_type const& /*use_memop*/)
{
- //BOOST_ASSERT_MSG(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la));
+ //BOOST_GEOMETRY_INDEX_ASSERT(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la),
+ // "incompatible ranges");
namespace sv = varray_detail;
for (; first_sm != last_sm ; ++first_sm, ++first_la)
@@ -1639,7 +1634,8 @@ private:
// Linear O(N).
void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::false_type const& /*use_memop*/)
{
- //BOOST_ASSERT_MSG(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la));
+ //BOOST_GEOMETRY_INDEX_ASSERT(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la),
+ // "incompatible ranges");
namespace sv = varray_detail;
for (; first_sm != last_sm ; ++first_sm, ++first_la)
@@ -1961,7 +1957,7 @@ public:
errh::check_iterator_end_eq(*this, first);
errh::check_iterator_end_eq(*this, last);
- //BOOST_ASSERT_MSG(0 <= n, "invalid range");
+ //BOOST_GEOMETRY_INDEX_ASSERT(0 <= n, "invalid range");
}
// basic
diff --git a/3party/boost/boost/geometry/index/detail/varray_detail.hpp b/3party/boost/boost/geometry/index/detail/varray_detail.hpp
index 962d4d8288..31b77c40fe 100644
--- a/3party/boost/boost/geometry/index/detail/varray_detail.hpp
+++ b/3party/boost/boost/geometry/index/detail/varray_detail.hpp
@@ -2,7 +2,7 @@
//
// varray details
//
-// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2012-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2013 Andrew Hundt.
//
// Use, modification and distribution is subject to the Boost Software License,
@@ -39,9 +39,13 @@
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
-#include <boost/utility/addressof.hpp>
+#include <boost/core/addressof.hpp>
#include <boost/iterator/iterator_traits.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+
// TODO - move vectors iterators optimization to the other, optional file instead of checking defines?
#if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
@@ -618,22 +622,22 @@ void construct(DisableTrivialInit const&,
// !BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 && p0
// which means that version with one parameter may take V const& v
-#define BOOST_PP_LOCAL_MACRO(n) \
-template <typename DisableTrivialInit, typename I, typename P BOOST_PP_ENUM_TRAILING_PARAMS(n, typename P) > \
+#define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT(N) \
+template <typename DisableTrivialInit, typename I, typename P BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
inline \
void construct(DisableTrivialInit const&, \
I pos, \
- BOOST_CONTAINER_PP_PARAM(P, p) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ BOOST_FWD_REF(P) p \
+ BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
{ \
typedef typename boost::iterator_value<I>::type V; \
new \
(static_cast<void*>(boost::addressof(*pos))) \
- V(p, BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); /*may throw*/ \
+ V(boost::forward<P>(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); /*may throw*/ \
} \
-//
-#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
-#include BOOST_PP_LOCAL_ITERATE()
+
+BOOST_MOVE_ITERATE_1TO9(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT)
+#undef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT
#endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
diff --git a/3party/boost/boost/geometry/index/equal_to.hpp b/3party/boost/boost/geometry/index/equal_to.hpp
index 5fbaa8209f..b0cf098f1d 100644
--- a/3party/boost/boost/geometry/index/equal_to.hpp
+++ b/3party/boost/boost/geometry/index/equal_to.hpp
@@ -24,6 +24,15 @@ struct equals
}
};
+template <typename Geometry, typename Tag>
+struct equals<Geometry *, Tag>
+{
+ inline static bool apply(const Geometry * g1, const Geometry * g2)
+ {
+ return g1 == g2;
+ }
+};
+
template <typename T>
struct equals<T, void>
{
diff --git a/3party/boost/boost/geometry/index/indexable.hpp b/3party/boost/boost/geometry/index/indexable.hpp
index 5270ca22e8..391b544f37 100644
--- a/3party/boost/boost/geometry/index/indexable.hpp
+++ b/3party/boost/boost/geometry/index/indexable.hpp
@@ -29,7 +29,11 @@ template <typename Indexable>
struct is_indexable
{
static const bool value =
- is_indexable_impl<Indexable, typename geometry::traits::tag<Indexable>::type>::value;
+ is_indexable_impl
+ <
+ Indexable,
+ typename geometry::tag<Indexable>::type
+ >::value;
};
/*!
diff --git a/3party/boost/boost/geometry/index/parameters.hpp b/3party/boost/boost/geometry/index/parameters.hpp
index 2516e6d710..2b94907686 100644
--- a/3party/boost/boost/geometry/index/parameters.hpp
+++ b/3party/boost/boost/geometry/index/parameters.hpp
@@ -20,7 +20,6 @@ namespace detail {
template <size_t MaxElements>
struct default_min_elements_s
{
- // TODO - assert MaxElements <= (std::numeric_limits<size_t>::max)()/3
static const size_t raw_value = (MaxElements * 3) / 10;
static const size_t value = 1 <= raw_value ? raw_value : 1;
};
@@ -34,7 +33,6 @@ inline size_t default_min_elements_d_calc(size_t max_elements, size_t min_elemen
{
if ( default_min_elements_d() == min_elements )
{
- // TODO - assert MaxElements <= (std::numeric_limits<size_t>::max)()/3
size_t raw_value = (max_elements * 3) / 10;
return 1 <= raw_value ? raw_value : 1;
}
@@ -45,7 +43,6 @@ inline size_t default_min_elements_d_calc(size_t max_elements, size_t min_elemen
template <size_t MaxElements>
struct default_rstar_reinserted_elements_s
{
- // TODO - assert MaxElements <= (std::numeric_limits<size_t>::max)()/3
static const size_t value = (MaxElements * 3) / 10;
};
@@ -58,7 +55,6 @@ inline size_t default_rstar_reinserted_elements_d_calc(size_t max_elements, size
{
if ( default_rstar_reinserted_elements_d() == reinserted_elements )
{
- // TODO - assert MaxElements <= (std::numeric_limits<size_t>::max)()/3
return (max_elements * 3) / 10;
}
@@ -74,8 +70,7 @@ inline size_t default_rstar_reinserted_elements_d_calc(size_t max_elements, size
\tparam MinElements Minimum number of elements in nodes. Default: 0.3*Max.
*/
template <size_t MaxElements,
- size_t MinElements = detail::default_min_elements_s<MaxElements>::value
->
+ size_t MinElements = detail::default_min_elements_s<MaxElements>::value>
struct linear
{
BOOST_MPL_ASSERT_MSG((0 < MinElements && 2*MinElements <= MaxElements+1),
diff --git a/3party/boost/boost/geometry/index/predicates.hpp b/3party/boost/boost/geometry/index/predicates.hpp
index 10033abff8..3bb1bf4d87 100644
--- a/3party/boost/boost/geometry/index/predicates.hpp
+++ b/3party/boost/boost/geometry/index/predicates.hpp
@@ -2,7 +2,7 @@
//
// Spatial query predicates
//
-// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -43,10 +43,15 @@ bgi::query(spatial_index, bgi::contains(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
-detail::spatial_predicate<Geometry, detail::contains_tag, false>
+detail::predicates::spatial_predicate<Geometry, detail::predicates::contains_tag, false>
contains(Geometry const& g)
{
- return detail::spatial_predicate<Geometry, detail::contains_tag, false>(g);
+ return detail::predicates::spatial_predicate
+ <
+ Geometry,
+ detail::predicates::contains_tag,
+ false
+ >(g);
}
/*!
@@ -68,10 +73,15 @@ bgi::query(spatial_index, bgi::covered_by(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
-detail::spatial_predicate<Geometry, detail::covered_by_tag, false>
+detail::predicates::spatial_predicate<Geometry, detail::predicates::covered_by_tag, false>
covered_by(Geometry const& g)
{
- return detail::spatial_predicate<Geometry, detail::covered_by_tag, false>(g);
+ return detail::predicates::spatial_predicate
+ <
+ Geometry,
+ detail::predicates::covered_by_tag,
+ false
+ >(g);
}
/*!
@@ -93,10 +103,15 @@ bgi::query(spatial_index, bgi::covers(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
-detail::spatial_predicate<Geometry, detail::covers_tag, false>
+detail::predicates::spatial_predicate<Geometry, detail::predicates::covers_tag, false>
covers(Geometry const& g)
{
- return detail::spatial_predicate<Geometry, detail::covers_tag, false>(g);
+ return detail::predicates::spatial_predicate
+ <
+ Geometry,
+ detail::predicates::covers_tag,
+ false
+ >(g);
}
/*!
@@ -118,10 +133,15 @@ bgi::query(spatial_index, bgi::disjoint(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
-detail::spatial_predicate<Geometry, detail::disjoint_tag, false>
+detail::predicates::spatial_predicate<Geometry, detail::predicates::disjoint_tag, false>
disjoint(Geometry const& g)
{
- return detail::spatial_predicate<Geometry, detail::disjoint_tag, false>(g);
+ return detail::predicates::spatial_predicate
+ <
+ Geometry,
+ detail::predicates::disjoint_tag,
+ false
+ >(g);
}
/*!
@@ -145,10 +165,15 @@ bgi::query(spatial_index, bgi::intersects(polygon), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
-detail::spatial_predicate<Geometry, detail::intersects_tag, false>
+detail::predicates::spatial_predicate<Geometry, detail::predicates::intersects_tag, false>
intersects(Geometry const& g)
{
- return detail::spatial_predicate<Geometry, detail::intersects_tag, false>(g);
+ return detail::predicates::spatial_predicate
+ <
+ Geometry,
+ detail::predicates::intersects_tag,
+ false
+ >(g);
}
/*!
@@ -170,10 +195,15 @@ bgi::query(spatial_index, bgi::overlaps(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
-detail::spatial_predicate<Geometry, detail::overlaps_tag, false>
+detail::predicates::spatial_predicate<Geometry, detail::predicates::overlaps_tag, false>
overlaps(Geometry const& g)
{
- return detail::spatial_predicate<Geometry, detail::overlaps_tag, false>(g);
+ return detail::predicates::spatial_predicate
+ <
+ Geometry,
+ detail::predicates::overlaps_tag,
+ false
+ >(g);
}
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -192,10 +222,15 @@ returns true.
\param g The Geometry object.
*/
template <typename Geometry> inline
-detail::spatial_predicate<Geometry, detail::touches_tag, false>
+detail::predicates::spatial_predicate<Geometry, detail::predicates::touches_tag, false>
touches(Geometry const& g)
{
- return detail::spatial_predicate<Geometry, detail::touches_tag, false>(g);
+ return detail::predicates::spatial_predicate
+ <
+ Geometry,
+ detail::predicates::touches_tag,
+ false
+ >(g);
}
#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -219,10 +254,15 @@ bgi::query(spatial_index, bgi::within(box), std::back_inserter(result));
\param g The Geometry object.
*/
template <typename Geometry> inline
-detail::spatial_predicate<Geometry, detail::within_tag, false>
+detail::predicates::spatial_predicate<Geometry, detail::predicates::within_tag, false>
within(Geometry const& g)
{
- return detail::spatial_predicate<Geometry, detail::within_tag, false>(g);
+ return detail::predicates::spatial_predicate
+ <
+ Geometry,
+ detail::predicates::within_tag,
+ false
+ >(g);
}
/*!
@@ -259,10 +299,10 @@ std::back_inserter(result));
\param pred The unary predicate function or function object.
*/
template <typename UnaryPredicate> inline
-detail::satisfies<UnaryPredicate, false>
+detail::predicates::satisfies<UnaryPredicate, false>
satisfies(UnaryPredicate const& pred)
{
- return detail::satisfies<UnaryPredicate, false>(pred);
+ return detail::predicates::satisfies<UnaryPredicate, false>(pred);
}
/*!
@@ -289,10 +329,10 @@ Only one \c nearest() predicate may be used in a query.
\param k The maximum number of values to return.
*/
template <typename Geometry> inline
-detail::nearest<Geometry>
+detail::predicates::nearest<Geometry>
nearest(Geometry const& geometry, unsigned k)
{
- return detail::nearest<Geometry>(geometry, k);
+ return detail::predicates::nearest<Geometry>(geometry, k);
}
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -319,15 +359,15 @@ Only one distance predicate (\c nearest() or \c path()) may be used in a query.
\param k The maximum number of values to return.
*/
template <typename SegmentOrLinestring> inline
-detail::path<SegmentOrLinestring>
+detail::predicates::path<SegmentOrLinestring>
path(SegmentOrLinestring const& linestring, unsigned k)
{
- return detail::path<SegmentOrLinestring>(linestring, k);
+ return detail::predicates::path<SegmentOrLinestring>(linestring, k);
}
#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
-namespace detail {
+namespace detail { namespace predicates {
// operator! generators
@@ -378,7 +418,7 @@ operator&&(boost::tuples::cons<Head, Tail> const& t, Pred const& p)
>::apply(t, p);
}
-} // namespace detail
+}} // namespace detail::predicates
}}} // namespace boost::geometry::index
diff --git a/3party/boost/boost/geometry/index/rtree.hpp b/3party/boost/boost/geometry/index/rtree.hpp
index 09f07ffe77..84c4da8a2a 100644
--- a/3party/boost/boost/geometry/index/rtree.hpp
+++ b/3party/boost/boost/geometry/index/rtree.hpp
@@ -3,7 +3,7 @@
// R-tree implementation
//
// Copyright (c) 2008 Federico J. Fernandez.
-// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -59,6 +59,7 @@
#include <boost/geometry/index/detail/algorithms/is_valid.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
+#include <boost/geometry/index/detail/rtree/visitors/iterator.hpp>
#include <boost/geometry/index/detail/rtree/visitors/remove.hpp>
#include <boost/geometry/index/detail/rtree/visitors/copy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
@@ -78,6 +79,7 @@
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
+#include <boost/geometry/index/detail/rtree/iterators.hpp>
#include <boost/geometry/index/detail/rtree/query_iterators.hpp>
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -96,12 +98,13 @@ namespace boost { namespace geometry { namespace index {
/*!
\brief The R-tree spatial index.
-This is self-balancing spatial index capable to store various types of Values and balancing algorithms.
+This is self-balancing spatial index capable to store various types of Values
+and balancing algorithms.
\par Parameters
The user must pass a type defining the Parameters which will
-be used in rtree creation process. This type is used e.g. to specify balancing algorithm
-with specific parameters like min and max number of elements in node.
+be used in rtree creation process. This type is used e.g. to specify balancing
+algorithm with specific parameters like min and max number of elements in node.
\par
Predefined algorithms with compile-time parameters are:
@@ -116,23 +119,31 @@ Predefined algorithms with run-time parameters are:
\li \c boost::geometry::index::dynamic_rstar.
\par IndexableGetter
-The object of IndexableGetter type translates from Value to Indexable each time r-tree requires it. Which means that this
-operation is done for each Value access. Therefore the IndexableGetter should return the Indexable by
-const reference instead of a value. Default one can translate all types adapted to Point, Box or Segment
-concepts (called Indexables). It also handles <tt>std::pair<Indexable, T></tt> and
-<tt>boost::tuple<Indexable, ...></tt>. For example, if <tt>std::pair<Box, int></tt> is stored in the
-container, the default IndexableGetter translates from <tt>std::pair<Box, int> const&</tt> to <tt>Box const&</tt>.
+The object of IndexableGetter type translates from Value to Indexable each time
+r-tree requires it. This means that this operation is done for each Value
+access. Therefore the IndexableGetter should return the Indexable by
+a reference type. The Indexable should not be calculated since it could harm
+the performance. The default IndexableGetter can translate all types adapted
+to Point, Box or Segment concepts (called Indexables). Furthermore, it can
+handle <tt>std::pair<Indexable, T></tt>, <tt>boost::tuple<Indexable, ...></tt>
+and <tt>std::tuple<Indexable, ...></tt> when possible. For example, for Value
+of type <tt>std::pair<Box, int></tt>, the default IndexableGetter translates
+from <tt>std::pair<Box, int> const&</tt> to <tt>Box const&</tt>.
\par EqualTo
-The object of EqualTo type compares Values and returns <tt>true</tt> if they're equal. It's similar to <tt>std::equal_to<></tt>.
-The default EqualTo returns the result of <tt>boost::geometry::equals()</tt> for types adapted to some Geometry concept
-defined in Boost.Geometry and the result of operator= for other types. Components of Pairs and Tuples are compared left-to-right.
+The object of EqualTo type compares Values and returns <tt>true</tt> if they
+are equal. It's similar to <tt>std::equal_to<></tt>. The default EqualTo
+returns the result of <tt>boost::geometry::equals()</tt> for types adapted to
+some Geometry concept defined in Boost.Geometry and the result of
+<tt>operator==</tt> for other types. Components of Pairs and Tuples are
+compared left-to-right.
\tparam Value The type of objects stored in the container.
\tparam Parameters Compile-time parameters.
\tparam IndexableGetter The function object extracting Indexable from Value.
\tparam EqualTo The function object comparing objects of type Value.
-\tparam Allocator The allocator used to allocate/deallocate memory, construct/destroy nodes and Values.
+\tparam Allocator The allocator used to allocate/deallocate memory,
+ construct/destroy nodes and Values.
*/
template <
typename Value,
@@ -188,7 +199,7 @@ private:
typedef typename allocators_type::node_pointer node_pointer;
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
- typedef detail::rtree::node_auto_ptr<value_type, options_type, translator_type, box_type, allocators_type> node_auto_ptr;
+ typedef detail::rtree::subtree_destroyer<value_type, options_type, translator_type, box_type, allocators_type> subtree_destroyer;
friend class detail::rtree::utilities::view<rtree>;
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -211,8 +222,17 @@ public:
/*! \brief Unsigned integral type used by the container. */
typedef typename allocators_type::size_type size_type;
- /*! \brief Type of const query iterator. */
- typedef index::detail::rtree::iterators::query_iterator<value_type, allocators_type> const_query_iterator;
+ /*! \brief Type of const iterator, category ForwardIterator. */
+ typedef index::detail::rtree::iterators::iterator
+ <
+ value_type, options_type, translator_type, box_type, allocators_type
+ > const_iterator;
+
+ /*! \brief Type of const query iterator, category ForwardIterator. */
+ typedef index::detail::rtree::iterators::query_iterator
+ <
+ value_type, allocators_type
+ > const_query_iterator;
public:
@@ -590,9 +610,9 @@ public:
}
/*!
- \brief Insert a range of values to the index.
+ \brief Insert a value created using convertible object or a range of values to the index.
- \param rng The range of values.
+ \param conv_or_rng An object of type convertible to value_type or a range of values.
\par Throws
\li If Value copy constructor or copy assignment throws.
@@ -604,17 +624,15 @@ public:
elements must not be inserted or removed. Other operations are allowed however
some of them may return invalid data.
*/
- template <typename Range>
- inline void insert(Range const& rng)
+ template <typename ConvertibleOrRange>
+ inline void insert(ConvertibleOrRange const& conv_or_rng)
{
- BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range));
+ typedef boost::mpl::bool_
+ <
+ boost::is_convertible<ConvertibleOrRange, value_type>::value
+ > is_conv_t;
- if ( !m_members.root )
- this->raw_create();
-
- typedef typename boost::range_const_iterator<Range>::type It;
- for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
- this->raw_insert(*it);
+ this->insert_dispatch(conv_or_rng, is_conv_t());
}
/*!
@@ -675,13 +693,13 @@ public:
}
/*!
- \brief Remove a range of values from the container.
+ \brief Remove value corresponding to an object convertible to it or a range of values from the container.
In contrast to the \c std::set or <tt>std::map erase()</tt> method
it removes values equal to these passed as a range. Furthermore, this method removes only
one value for each one passed in the range, not all equal values.
- \param rng The range of values.
+ \param conv_or_rng The object of type convertible to value_type or a range of values.
\return The number of removed values.
@@ -695,16 +713,15 @@ public:
elements must not be inserted or removed. Other operations are allowed however
some of them may return invalid data.
*/
- template <typename Range>
- inline size_type remove(Range const& rng)
+ template <typename ConvertibleOrRange>
+ inline size_type remove(ConvertibleOrRange const& conv_or_rng)
{
- BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range));
+ typedef boost::mpl::bool_
+ <
+ boost::is_convertible<ConvertibleOrRange, value_type>::value
+ > is_conv_t;
- size_type result = 0;
- typedef typename boost::range_const_iterator<Range>::type It;
- for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
- result += this->raw_remove(*it);
- return result;
+ return this->remove_dispatch(conv_or_rng, is_conv_t());
}
/*!
@@ -760,6 +777,27 @@ public:
tree.query(bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
// return 5 elements nearest to pt and elements are intersecting box
tree.query(bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
+
+ // For each found value do_something (it is a type of function object)
+ tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator(do_something()));
+
+ // For each value stored in the rtree do_something
+ // always_true is a type of function object always returning true
+ tree.query(bgi::satisfies(always_true()),
+ boost::make_function_output_iterator(do_something()));
+
+ // C++11 (lambda expression)
+ tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator([](value_type const& val){
+ // do something
+ }));
+
+ // C++14 (generic lambda expression)
+ tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator([](auto const& val){
+ // do something
+ }));
\endverbatim
\par Throws
@@ -768,7 +806,7 @@ public:
\warning
Only one \c nearest() perdicate may be passed to the query. Passing more of them results in compile-time error.
-
+
\param predicates Predicates.
\param out_it The output iterator, e.g. generated by std::back_inserter().
@@ -788,11 +826,11 @@ public:
}
/*!
- \brief Returns the query iterator pointing at the begin of the query range.
+ \brief Returns a query iterator pointing at the begin of the query range.
+
+ This method returns an iterator which may be used to perform iterative queries.
+ For the information about predicates which may be passed to this method see query().
- This method returns the iterator which may be used to perform iterative queries. For the information
- about the predicates which may be passed to this method see query().
-
\par Example
\verbatim
for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
@@ -802,12 +840,29 @@ public:
if ( has_enough_nearest_values() )
break;
}
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin(bgi::nearest(pt, 3)) ; it != tree.qend() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++14 (generic lambda expression)
+ std::for_each(tree.qbegin(bgi::nearest(pt, 3)), tree.qend(), [](auto const& val){
+ // do something with value
+ });
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
If predicates copy throws.
If allocation throws.
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
\param predicates Predicates.
\return The iterator pointing at the begin of the query range.
@@ -819,10 +874,10 @@ public:
}
/*!
- \brief Returns the query iterator pointing at the end of the query range.
+ \brief Returns a query iterator pointing at the end of the query range.
+
+ This method returns an iterator which may be used to check if the query has ended.
- This method returns the iterator which may be used to check if the query has ended.
-
\par Example
\verbatim
for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
@@ -832,10 +887,27 @@ public:
if ( has_enough_nearest_values() )
break;
}
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin(bgi::nearest(pt, 3)) ; it != tree.qend() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++14 (generic lambda expression)
+ std::for_each(tree.qbegin(bgi::nearest(pt, 3)), tree.qend(), [](auto const& val){
+ // do something with value
+ });
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
Nothing
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
\return The iterator pointing at the end of the query range.
*/
@@ -848,10 +920,10 @@ public:
private:
#endif
/*!
- \brief Returns the query iterator pointing at the begin of the query range.
+ \brief Returns a query iterator pointing at the begin of the query range.
- This method returns the iterator which may be used to perform iterative queries. For the information
- about the predicates which may be passed to this method see query().
+ This method returns an iterator which may be used to perform iterative queries.
+ For the information about predicates which may be passed to this method see query().
The type of the returned iterator depends on the type of passed Predicates but the iterator of this type
may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator
@@ -861,16 +933,24 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() - it requires both iterators of the same type
- std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
+ std::copy(tree.qbegin_(bgi::intersects(box)), tree.qend_(bgi::intersects(box)), std::back_inserter(result));
// Store the result in the container using std::copy() and type-erased iterators
- Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
- Rtree::const_query_iterator last = tree.qend();
+ Rtree::const_query_iterator first = tree.qbegin_(bgi::intersects(box));
+ Rtree::const_query_iterator last = tree.qend_();
std::copy(first, last, std::back_inserter(result));
// Boost.Typeof
typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
- for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
+ for ( Iter it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
+ {
+ // do something with value
+ if ( has_enough_nearest_values() )
+ break;
+ }
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
@@ -878,10 +958,16 @@ private:
}
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
If predicates copy throws.
If allocation throws.
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
\param predicates Predicates.
\return The iterator pointing at the begin of the query range.
@@ -931,12 +1017,18 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() - it requires both iterators of the same type
- std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
+ std::copy(tree.qbegin_(bgi::intersects(box)), tree.qend_(bgi::intersects(box)), std::back_inserter(result));
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
If predicates copy throws.
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
\param predicates Predicates.
\return The iterator pointing at the end of the query range.
@@ -983,13 +1075,21 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() and type-erased iterators
- Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
- Rtree::const_query_iterator last = tree.qend();
+ Rtree::const_query_iterator first = tree.qbegin_(bgi::intersects(box));
+ Rtree::const_query_iterator last = tree.qend_();
std::copy(first, last, std::back_inserter(result));
// Boost.Typeof
typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
- for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
+ for ( Iter it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
+ {
+ // do something with value
+ if ( has_enough_nearest_values() )
+ break;
+ }
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
@@ -997,8 +1097,14 @@ private:
}
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
Nothing
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
\return The iterator pointing at the end of the query range.
*/
@@ -1011,6 +1117,88 @@ private:
public:
/*!
+ \brief Returns the iterator pointing at the begin of the rtree values range.
+
+ This method returns the iterator which may be used to iterate over all values
+ stored in the rtree.
+
+ \par Example
+ \verbatim
+ // Copy all values into the vector
+ std::copy(tree.begin(), tree.end(), std::back_inserter(vec));
+
+ for ( Rtree::const_iterator it = tree.begin() ; it != tree.end() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++11 (auto)
+ for ( auto it = tree.begin() ; it != tree.end() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++14 (generic lambda expression)
+ std::for_each(tree.begin(), tree.end(), [](auto const& val){
+ // do something with value
+ })
+ \endverbatim
+
+ \par Iterator category
+ ForwardIterator
+
+ \par Throws
+ If allocation throws.
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
+ \return The iterator pointing at the begin of the range.
+ */
+ const_iterator begin() const
+ {
+ if ( !m_members.root )
+ return const_iterator();
+
+ return const_iterator(m_members.root);
+ }
+
+ /*!
+ \brief Returns the iterator pointing at the end of the rtree values range.
+
+ This method returns the iterator which may be compared with the iterator returned by begin()
+ in order to check if the iteration has ended.
+
+ \par Example
+ \verbatim
+ for ( Rtree::const_iterator it = tree.begin() ; it != tree.end() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++11 (lambda expression)
+ std::for_each(tree.begin(), tree.end(), [](value_type const& val){
+ // do something with value
+ })
+ \endverbatim
+
+ \par Iterator category
+ ForwardIterator
+
+ \par Throws
+ Nothing.
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
+ \return The iterator pointing at the end of the range.
+ */
+ const_iterator end() const
+ {
+ return const_iterator();
+ }
+
+ /*!
\brief Returns the number of stored values.
\return The number of stored values.
@@ -1091,15 +1279,36 @@ public:
template <typename ValueOrIndexable>
size_type count(ValueOrIndexable const& vori) const
{
- if ( !m_members.root )
- return 0;
-
- detail::rtree::visitors::count<ValueOrIndexable, value_type, options_type, translator_type, box_type, allocators_type>
- count_v(vori, m_members.translator());
-
- detail::rtree::apply_visitor(count_v, *m_members.root);
-
- return count_v.found_count;
+ // the input should be convertible to Value or Indexable type
+
+ enum { as_val = 0, as_ind, dont_know };
+ typedef boost::mpl::int_
+ <
+ boost::is_same<ValueOrIndexable, value_type>::value ?
+ as_val :
+ boost::is_same<ValueOrIndexable, indexable_type>::value ?
+ as_ind :
+ boost::is_convertible<ValueOrIndexable, indexable_type>::value ?
+ as_ind :
+ boost::is_convertible<ValueOrIndexable, value_type>::value ?
+ as_val :
+ dont_know
+ > variant;
+
+ BOOST_MPL_ASSERT_MSG((variant::value != dont_know),
+ PASSED_OBJECT_NOT_CONVERTIBLE_TO_VALUE_NOR_INDEXABLE_TYPE,
+ (ValueOrIndexable));
+
+ typedef typename boost::mpl::if_c
+ <
+ variant::value == as_val,
+ value_type,
+ indexable_type
+ >::type value_or_indexable;
+
+ // NOTE: If an object of convertible but not the same type is passed
+ // into the function, here a temporary will be created.
+ return this->template raw_count<value_or_indexable>(vori);
}
/*!
@@ -1217,6 +1426,7 @@ private:
inline void raw_insert(value_type const& value)
{
BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
+ // CONSIDER: alternative - ignore invalid indexable or throw an exception
BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(m_members.translator()(value)), "Indexable is invalid");
detail::rtree::visitors::insert<
@@ -1334,7 +1544,7 @@ private:
dst.m_members.parameters() = src.m_members.parameters();
}
- // TODO use node_auto_ptr
+ // TODO use subtree_destroyer
if ( dst.m_members.root )
{
detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
@@ -1349,6 +1559,86 @@ private:
}
/*!
+ \brief Insert a value corresponding to convertible object into the index.
+
+ \param val_conv The object convertible to value.
+
+ \par Exception-safety
+ basic
+ */
+ template <typename ValueConvertible>
+ inline void insert_dispatch(ValueConvertible const& val_conv,
+ boost::mpl::bool_<true> const& /*is_convertible*/)
+ {
+ if ( !m_members.root )
+ this->raw_create();
+
+ this->raw_insert(val_conv);
+ }
+
+ /*!
+ \brief Insert a range of values into the index.
+
+ \param rng The range of values.
+
+ \par Exception-safety
+ basic
+ */
+ template <typename Range>
+ inline void insert_dispatch(Range const& rng,
+ boost::mpl::bool_<false> const& /*is_convertible*/)
+ {
+ BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value),
+ PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE,
+ (Range));
+
+ if ( !m_members.root )
+ this->raw_create();
+
+ typedef typename boost::range_const_iterator<Range>::type It;
+ for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
+ this->raw_insert(*it);
+ }
+
+ /*!
+ \brief Remove a value corresponding to convertible object from the index.
+
+ \param val_conv The object convertible to value.
+
+ \par Exception-safety
+ basic
+ */
+ template <typename ValueConvertible>
+ inline size_type remove_dispatch(ValueConvertible const& val_conv,
+ boost::mpl::bool_<true> const& /*is_convertible*/)
+ {
+ return this->raw_remove(val_conv);
+ }
+
+ /*!
+ \brief Remove a range of values from the index.
+
+ \param rng The range of values which will be removed from the container.
+
+ \par Exception-safety
+ basic
+ */
+ template <typename Range>
+ inline size_type remove_dispatch(Range const& rng,
+ boost::mpl::bool_<false> const& /*is_convertible*/)
+ {
+ BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value),
+ PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE,
+ (Range));
+
+ size_type result = 0;
+ typedef typename boost::range_const_iterator<Range>::type It;
+ for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
+ result += this->raw_remove(*it);
+ return result;
+ }
+
+ /*!
\brief Return values meeting predicates.
\par Exception-safety
@@ -1390,6 +1680,33 @@ private:
return distance_v.finish();
}
+
+ /*!
+ \brief Count elements corresponding to value or indexable.
+
+ \par Exception-safety
+ strong
+ */
+ template <typename ValueOrIndexable>
+ size_type raw_count(ValueOrIndexable const& vori) const
+ {
+ if ( !m_members.root )
+ return 0;
+
+ detail::rtree::visitors::count
+ <
+ ValueOrIndexable,
+ value_type,
+ options_type,
+ translator_type,
+ box_type,
+ allocators_type
+ > count_v(vori, m_members.translator());
+
+ detail::rtree::apply_visitor(count_v, *m_members.root);
+
+ return count_v.found_count;
+ }
struct members_holder
: public translator_type
@@ -1456,7 +1773,8 @@ It calls <tt>rtree::insert(value_type const&)</tt>.
\param v The value which will be stored in the index.
*/
template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
-inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Value const& v)
+inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
+ Value const& v)
{
tree.insert(v);
}
@@ -1472,26 +1790,30 @@ It calls <tt>rtree::insert(Iterator, Iterator)</tt>.
\param first The beginning of the range of values.
\param last The end of the range of values.
*/
-template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Iterator>
-inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Iterator first, Iterator last)
+template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
+ typename Iterator>
+inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
+ Iterator first, Iterator last)
{
tree.insert(first, last);
}
/*!
-\brief Insert a range of values to the index.
+\brief Insert a value created using convertible object or a range of values to the index.
-It calls <tt>rtree::insert(Range const&)</tt>.
+It calls <tt>rtree::insert(ConvertibleOrRange const&)</tt>.
\ingroup rtree_functions
-\param tree The spatial index.
-\param rng The range of values.
+\param tree The spatial index.
+\param conv_or_rng The object of type convertible to value_type or a range of values.
*/
-template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Range>
-inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Range const& rng)
+template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
+ typename ConvertibleOrRange>
+inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
+ ConvertibleOrRange const& conv_or_rng)
{
- tree.insert(rng);
+ tree.insert(conv_or_rng);
}
/*!
@@ -1511,7 +1833,8 @@ It calls <tt>rtree::remove(value_type const&)</tt>.
*/
template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
-remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Value const& v)
+remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
+ Value const& v)
{
return tree.remove(v);
}
@@ -1534,34 +1857,39 @@ It calls <tt>rtree::remove(Iterator, Iterator)</tt>.
\return The number of removed values.
*/
-template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Iterator>
+template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
+ typename Iterator>
inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
-remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Iterator first, Iterator last)
+remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
+ Iterator first, Iterator last)
{
return tree.remove(first, last);
}
/*!
-\brief Remove a range of values from the container.
+\brief Remove a value corresponding to an object convertible to it or a range of values from the container.
-Remove a range of values from the container. In contrast to the \c std::set or <tt>std::map erase()</tt> method
+Remove a value corresponding to an object convertible to it or a range of values from the container.
+In contrast to the \c std::set or <tt>std::map erase()</tt> method
it removes values equal to these passed as a range. Furthermore this method removes only
one value for each one passed in the range, not all equal values.
-It calls <tt>rtree::remove(Range const&)</tt>.
+It calls <tt>rtree::remove(ConvertibleOrRange const&)</tt>.
\ingroup rtree_functions
-\param tree The spatial index.
-\param rng The range of values.
+\param tree The spatial index.
+\param conv_or_rng The object of type convertible to value_type or the range of values.
\return The number of removed values.
*/
-template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Range>
+template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
+ typename ConvertibleOrRange>
inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
-remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Range const& rng)
+remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
+ ConvertibleOrRange const& conv_or_rng)
{
- return tree.remove(rng);
+ return tree.remove(conv_or_rng);
}
/*!
@@ -1617,6 +1945,10 @@ bgi::query(tree, bgi::intersects(poly) && !bgi::within(box), std::back_inserter(
bgi::query(tree, bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
// return 5 elements nearest to pt and elements are intersecting box
bgi::query(tree, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
+
+// For each found value do_something (it is a type of function object)
+tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator(do_something()));
\endverbatim
\par Throws
@@ -1651,20 +1983,19 @@ about the predicates which may be passed to this method see query().
\par Example
\verbatim
-
-for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
- it != qend(tree) ; ++it )
-{
- // do something with value
- if ( has_enough_nearest_values() )
- break;
-}
+std::for_each(bgi::qbegin(tree, bgi::nearest(pt, 3)), bgi::qend(tree), do_something());
\endverbatim
+\par Iterator category
+ForwardIterator
+
\par Throws
If predicates copy throws.
If allocation throws.
+\warning
+The modification of the rtree may invalidate the iterators.
+
\ingroup rtree_functions
\param tree The rtree.
@@ -1688,19 +2019,18 @@ This method returns the iterator which may be used to check if the query has end
\par Example
\verbatim
-
-for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
- it != qend(tree) ; ++it )
-{
- // do something with value
- if ( has_enough_nearest_values() )
- break;
-}
+std::for_each(bgi::qbegin(tree, bgi::nearest(pt, 3)), bgi::qend(tree), do_something());
\endverbatim
+\par Iterator category
+ForwardIterator
+
\par Throws
Nothing
+\warning
+The modification of the rtree may invalidate the iterators.
+
\ingroup rtree_functions
\return The iterator pointing at the end of the query range.
@@ -1713,6 +2043,72 @@ qend(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
}
/*!
+\brief Returns the iterator pointing at the begin of the rtree values range.
+
+This method returns the iterator which may be used to iterate over all values
+stored in the rtree.
+
+\par Example
+\verbatim
+std::for_each(bgi::begin(tree), bgi::end(tree), do_something());
+// the same as
+std::for_each(boost::begin(tree), boost::end(tree), do_something());
+\endverbatim
+
+\par Iterator category
+ForwardIterator
+
+\par Throws
+If allocation throws.
+
+\warning
+The modification of the rtree may invalidate the iterators.
+
+\ingroup rtree_functions
+
+\return The iterator pointing at the begin of the range.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
+typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_iterator
+begin(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
+{
+ return tree.begin();
+}
+
+/*!
+\brief Returns the iterator pointing at the end of the rtree values range.
+
+This method returns the iterator which may be compared with the iterator returned by begin()
+in order to check if the iteration has ended.
+
+\par Example
+\verbatim
+std::for_each(bgi::begin(tree), bgi::end(tree), do_something());
+// the same as
+std::for_each(boost::begin(tree), boost::end(tree), do_something());
+\endverbatim
+
+\par Iterator category
+ForwardIterator
+
+\par Throws
+Nothing.
+
+\warning
+The modification of the rtree may invalidate the iterators.
+
+\ingroup rtree_functions
+
+\return The iterator pointing at the end of the range.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
+typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_iterator
+end(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
+{
+ return tree.end();
+}
+
+/*!
\brief Remove all values from the index.
It calls \c rtree::clear().
@@ -1798,6 +2194,23 @@ inline void swap(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> &
}}} // namespace boost::geometry::index
+// Boost.Range adaptation
+namespace boost {
+
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
+struct range_mutable_iterator
+ <
+ boost::geometry::index::rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>
+ >
+{
+ typedef typename boost::geometry::index::rtree
+ <
+ Value, Parameters, IndexableGetter, EqualTo, Allocator
+ >::const_iterator type;
+};
+
+} // namespace boost
+
// TODO: don't include the implementation at the end of the file
#include <boost/geometry/algorithms/detail/comparable_distance/implementation.hpp>
diff --git a/3party/boost/boost/geometry/io/svg/svg_mapper.hpp b/3party/boost/boost/geometry/io/svg/svg_mapper.hpp
index b53fef2ceb..c8e63d5ab7 100644
--- a/3party/boost/boost/geometry/io/svg/svg_mapper.hpp
+++ b/3party/boost/boost/geometry/io/svg/svg_mapper.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -16,6 +21,7 @@
#include <vector>
+#include <boost/config.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
@@ -31,15 +37,11 @@
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/is_empty.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/algorithms/envelope.hpp>
-#include <boost/geometry/multi/algorithms/num_points.hpp>
-
#include <boost/geometry/io/svg/write_svg.hpp>
// Helper geometries (all points are transformed to integer-points)
@@ -97,6 +99,11 @@ struct svg_map<box_tag, Box>
Box const& box, TransformStrategy const& strategy)
{
model::box<detail::svg::svg_point_type> ibox;
+
+ // Fix bug in gcc compiler warning for possible uninitialation
+#if defined(BOOST_GCC)
+ geometry::assign_zero(ibox);
+#endif
geometry::transform(box, ibox, strategy);
stream << geometry::svg(ibox, style, size) << std::endl;
@@ -307,7 +314,7 @@ public :
template <typename Geometry>
void add(Geometry const& geometry)
{
- if (num_points(geometry) > 0)
+ if (! geometry::is_empty(geometry))
{
expand(m_bounding_box,
return_envelope
diff --git a/3party/boost/boost/geometry/io/wkt/read.hpp b/3party/boost/boost/geometry/io/wkt/read.hpp
index 748eecdbe6..2415f21a69 100644
--- a/3party/boost/boost/geometry/io/wkt/read.hpp
+++ b/3party/boost/boost/geometry/io/wkt/read.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -29,6 +34,7 @@
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
@@ -38,6 +44,7 @@
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/mutable_range.hpp>
#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -98,7 +105,9 @@ namespace detail { namespace wkt
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
-template <typename Point, std::size_t Dimension, std::size_t DimensionCount>
+template <typename Point,
+ std::size_t Dimension = 0,
+ std::size_t DimensionCount = geometry::dimension<Point>::value>
struct parsing_assigner
{
static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
@@ -208,12 +217,7 @@ struct container_inserter
while (it != end && *it != ")")
{
- parsing_assigner
- <
- Point,
- 0,
- dimension<Point>::value
- >::apply(it, end, point, wkt);
+ parsing_assigner<Point>::apply(it, end, point, wkt);
out = point;
++out;
if (it != end && *it == ",")
@@ -227,35 +231,94 @@ struct container_inserter
};
+template <typename Geometry,
+ closure_selector Closure = closure<Geometry>::value>
+struct stateful_range_appender
+{
+ typedef typename geometry::point_type<Geometry>::type point_type;
+
+ // NOTE: Geometry is a reference
+ inline void append(Geometry geom, point_type const& point, bool)
+ {
+ geometry::append(geom, point);
+ }
+};
+
+template <typename Geometry>
+struct stateful_range_appender<Geometry, open>
+{
+ typedef typename geometry::point_type<Geometry>::type point_type;
+ typedef typename boost::range_size
+ <
+ typename util::bare_type<Geometry>::type
+ >::type size_type;
+
+ BOOST_STATIC_ASSERT(( boost::is_same
+ <
+ typename tag<Geometry>::type,
+ ring_tag
+ >::value ));
+
+ inline stateful_range_appender()
+ : pt_index(0)
+ {}
+
+ // NOTE: Geometry is a reference
+ inline void append(Geometry geom, point_type const& point, bool is_next_expected)
+ {
+ bool should_append = true;
+
+ if (pt_index == 0)
+ {
+ first_point = point;
+ //should_append = true;
+ }
+ else
+ {
+ // NOTE: if there is not enough Points, they're always appended
+ should_append
+ = is_next_expected
+ || pt_index < core_detail::closure::minimum_ring_size<open>::value
+ || !detail::equals::equals_point_point(point, first_point);
+ }
+ ++pt_index;
+
+ if (should_append)
+ {
+ geometry::append(geom, point);
+ }
+ }
+
+private:
+ size_type pt_index;
+ point_type first_point;
+};
+
// 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;
+ typedef typename geometry::point_type<Geometry>::type point_type;
static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
- std::string const& wkt, Geometry out)
+ std::string const& wkt, Geometry out)
{
handle_open_parenthesis(it, end, wkt);
- point_type point;
+ stateful_range_appender<Geometry> appender;
// 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 == ",")
+ point_type point;
+
+ parsing_assigner<point_type>::apply(it, end, point, wkt);
+
+ bool const is_next_expected = it != end && *it == ",";
+
+ appender.append(out, point, is_next_expected);
+
+ if (is_next_expected)
{
++it;
}
@@ -276,7 +339,7 @@ struct point_parser
std::string const& wkt, P& point)
{
handle_open_parenthesis(it, end, wkt);
- parsing_assigner<P, 0, dimension<P>::value>::apply(it, end, point, wkt);
+ parsing_assigner<P>::apply(it, end, point, wkt);
handle_close_parenthesis(it, end, wkt);
}
};
@@ -512,7 +575,7 @@ 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);
+ parsing_assigner<P>::apply(it, end, point, wkt);
}
};
@@ -617,7 +680,7 @@ struct box_parser
}
check_end(it, end, wkt);
- int index = 0;
+ unsigned int index = 0;
std::size_t n = boost::size(points);
if (n == 2)
{
diff --git a/3party/boost/boost/geometry/io/wkt/write.hpp b/3party/boost/boost/geometry/io/wkt/write.hpp
index 6c1a2e153e..f16c0cab76 100644
--- a/3party/boost/boost/geometry/io/wkt/write.hpp
+++ b/3party/boost/boost/geometry/io/wkt/write.hpp
@@ -1,9 +1,14 @@
// 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.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -20,6 +25,7 @@
#include <boost/array.hpp>
#include <boost/range.hpp>
+
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
@@ -27,7 +33,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/convert.hpp>
-#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -149,7 +155,7 @@ struct wkt_range
// optionally, close range to ring by repeating the first point
if (force_closed
&& boost::size(range) > 1
- && geometry::disjoint(*begin, *(end - 1)))
+ && detail::disjoint::disjoint_point_point(*begin, *(end - 1)))
{
os << ",";
stream_type::apply(os, *begin);
diff --git a/3party/boost/boost/geometry/iterators/closing_iterator.hpp b/3party/boost/boost/geometry/iterators/closing_iterator.hpp
index 7cd8fa0150..e263f3aafb 100644
--- a/3party/boost/boost/geometry/iterators/closing_iterator.hpp
+++ b/3party/boost/boost/geometry/iterators/closing_iterator.hpp
@@ -28,8 +28,9 @@ 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 It's const iterator treating the Range as one containing non-mutable elements.
+ For both "closing_iterator<Range> and "closing_iterator<Range const>
+ const reference is always returned when dereferenced.
\note This class is normally used from "closeable_view" if Close==true
*/
template <typename Range>
@@ -41,12 +42,14 @@ struct closing_iterator
boost::random_access_traversal_tag
>
{
+ typedef typename boost::range_difference<Range>::type difference_type;
+
/// 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_size(static_cast<difference_type>(boost::size(range)))
, m_index(0)
{}
@@ -55,8 +58,8 @@ struct closing_iterator
: m_range(&range)
, m_iterator(boost::end(range))
, m_end(boost::end(range))
- , m_size(boost::size(range))
- , m_index(m_size + 1)
+ , m_size(static_cast<difference_type>(boost::size(range)))
+ , m_index((m_size == 0) ? 0 : m_size + 1)
{}
/// Default constructor
@@ -66,18 +69,6 @@ struct closing_iterator
, 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;
diff --git a/3party/boost/boost/geometry/iterators/concatenate_iterator.hpp b/3party/boost/boost/geometry/iterators/concatenate_iterator.hpp
index e97061e1a1..ea5728d0bc 100644
--- a/3party/boost/boost/geometry/iterators/concatenate_iterator.hpp
+++ b/3party/boost/boost/geometry/iterators/concatenate_iterator.hpp
@@ -10,7 +10,6 @@
#ifndef BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/iterator.hpp>
@@ -23,13 +22,20 @@ namespace boost { namespace geometry
-template <typename Iterator1, typename Iterator2, typename Value>
+template
+<
+ typename Iterator1,
+ typename Iterator2,
+ typename Value,
+ typename Reference = Value&
+>
class concatenate_iterator
: public boost::iterator_facade
<
- concatenate_iterator<Iterator1, Iterator2, Value>,
+ concatenate_iterator<Iterator1, Iterator2, Value, Reference>,
Value,
- boost::bidirectional_traversal_tag
+ boost::bidirectional_traversal_tag,
+ Reference
>
{
private:
@@ -54,9 +60,20 @@ public:
: m_it1(end1), m_end1(end1), m_begin2(begin2), m_it2(end2)
{}
- template <typename OtherIt1, typename OtherIt2, typename OtherValue>
- concatenate_iterator
- (concatenate_iterator<OtherIt1, OtherIt2, OtherValue> const& other)
+ template
+ <
+ typename OtherIt1,
+ typename OtherIt2,
+ typename OtherValue,
+ typename OtherReference
+ >
+ concatenate_iterator(concatenate_iterator
+ <
+ OtherIt1,
+ OtherIt2,
+ OtherValue,
+ OtherReference
+ > const& other)
: m_it1(other.m_it1)
, m_end1(other.m_end1)
, m_begin2(other.m_begin2)
@@ -71,32 +88,13 @@ public:
(types<OtherIt1, OtherIt2>));
}
- template <typename OtherIt1, typename OtherIt2, typename OtherValue>
- concatenate_iterator
- operator=(concatenate_iterator<OtherIt1, OtherIt2, OtherValue> const& other)
- {
- static const bool are_conv
- = boost::is_convertible<OtherIt1, Iterator1>::value
- && boost::is_convertible<OtherIt2, Iterator2>::value;
-
- BOOST_MPL_ASSERT_MSG((are_conv),
- NOT_CONVERTIBLE,
- (types<OtherIt1, OtherIt2>));
-
- m_it1 = other.m_it1;
- m_end1 = other.m_end1;
- m_begin2 = other.m_begin2;
- m_it2 = other.m_it2;
- return *this;
- }
-
private:
friend class boost::iterator_core_access;
- template <typename It1, typename It2, typename V>
+ template <typename It1, typename It2, typename V, typename R>
friend class concatenate_iterator;
- inline Value& dereference() const
+ inline Reference dereference() const
{
if ( m_it1 == m_end1 )
{
@@ -105,12 +103,19 @@ private:
return *m_it1;
}
- template <typename OtherIt1, typename OtherIt2, typename OtherValue>
+ template
+ <
+ typename OtherIt1,
+ typename OtherIt2,
+ typename OtherValue,
+ typename OtherReference
+ >
inline bool equal(concatenate_iterator
<
OtherIt1,
OtherIt2,
- OtherValue
+ OtherValue,
+ OtherReference
> const& other) const
{
return m_it1 == other.m_it1 && m_it2 == other.m_it2;
diff --git a/3party/boost/boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp b/3party/boost/boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp
new file mode 100644
index 0000000000..b2239fb8dd
--- /dev/null
+++ b/3party/boost/boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp
@@ -0,0 +1,66 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_INNER_RANGE_TYPE_HPP
+#define BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_INNER_RANGE_TYPE_HPP
+
+#include <boost/range.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/mpl/if.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace point_iterator
+{
+
+
+template
+<
+ typename Geometry,
+ typename Tag = typename tag<Geometry>::type
+>
+struct inner_range_type
+{
+ typedef typename boost::mpl::if_c
+ <
+ !boost::is_const<Geometry>::type::value,
+ typename boost::range_value<Geometry>::type,
+ typename boost::range_value<Geometry>::type const
+ >::type type;
+};
+
+
+template <typename Polygon>
+struct inner_range_type<Polygon, polygon_tag>
+{
+ typedef typename boost::mpl::if_c
+ <
+ !boost::is_const<Polygon>::type::value,
+ typename geometry::ring_type<Polygon>::type,
+ typename geometry::ring_type<Polygon>::type const
+ >::type type;
+};
+
+
+}} // namespace detail::point_iterator
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_INNER_RANGE_TYPE_HPP
diff --git a/3party/boost/boost/geometry/iterators/detail/point_iterator/iterator_type.hpp b/3party/boost/boost/geometry/iterators/detail/point_iterator/iterator_type.hpp
new file mode 100644
index 0000000000..a7805b127b
--- /dev/null
+++ b/3party/boost/boost/geometry/iterators/detail/point_iterator/iterator_type.hpp
@@ -0,0 +1,136 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_ITERATOR_TYPE_HPP
+#define BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_ITERATOR_TYPE_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/iterators/flatten_iterator.hpp>
+#include <boost/geometry/iterators/concatenate_iterator.hpp>
+
+#include <boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp>
+#include <boost/geometry/iterators/detail/point_iterator/value_type.hpp>
+
+#include <boost/geometry/iterators/dispatch/point_iterator.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace point_iterator
+{
+
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct iterator_type
+ : not_implemented<Geometry>
+{};
+
+
+
+
+template <typename Linestring>
+struct iterator_type<Linestring, linestring_tag>
+{
+ typedef typename boost::range_iterator<Linestring>::type type;
+};
+
+
+template <typename Ring>
+struct iterator_type<Ring, ring_tag>
+{
+ typedef typename boost::range_iterator<Ring>::type type;
+};
+
+
+template <typename Polygon>
+class iterator_type<Polygon, polygon_tag>
+{
+private:
+ typedef typename inner_range_type<Polygon>::type inner_range;
+
+public:
+ typedef concatenate_iterator
+ <
+ typename boost::range_iterator<inner_range>::type,
+ flatten_iterator
+ <
+ typename boost::range_iterator
+ <
+ typename geometry::interior_type<Polygon>::type
+ >::type,
+ typename iterator_type<inner_range>::type,
+ typename value_type<Polygon>::type,
+ dispatch::points_begin<inner_range>,
+ dispatch::points_end<inner_range>
+ >,
+ typename value_type<Polygon>::type
+ > type;
+};
+
+
+template <typename MultiPoint>
+struct iterator_type<MultiPoint, multi_point_tag>
+{
+ typedef typename boost::range_iterator<MultiPoint>::type type;
+};
+
+
+template <typename MultiLinestring>
+class iterator_type<MultiLinestring, multi_linestring_tag>
+{
+private:
+ typedef typename inner_range_type<MultiLinestring>::type inner_range;
+
+public:
+ typedef flatten_iterator
+ <
+ typename boost::range_iterator<MultiLinestring>::type,
+ typename iterator_type<inner_range>::type,
+ typename value_type<MultiLinestring>::type,
+ dispatch::points_begin<inner_range>,
+ dispatch::points_end<inner_range>
+ > type;
+};
+
+
+template <typename MultiPolygon>
+class iterator_type<MultiPolygon, multi_polygon_tag>
+{
+private:
+ typedef typename inner_range_type<MultiPolygon>::type inner_range;
+
+public:
+ typedef flatten_iterator
+ <
+ typename boost::range_iterator<MultiPolygon>::type,
+ typename iterator_type<inner_range>::type,
+ typename value_type<MultiPolygon>::type,
+ dispatch::points_begin<inner_range>,
+ dispatch::points_end<inner_range>
+ > type;
+};
+
+
+}} // namespace detail::point_iterator
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_ITERATOR_TYPE_HPP
diff --git a/3party/boost/boost/geometry/iterators/detail/point_iterator/value_type.hpp b/3party/boost/boost/geometry/iterators/detail/point_iterator/value_type.hpp
new file mode 100644
index 0000000000..7cdf366391
--- /dev/null
+++ b/3party/boost/boost/geometry/iterators/detail/point_iterator/value_type.hpp
@@ -0,0 +1,47 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_VALUE_TYPE_HPP
+#define BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_VALUE_TYPE_HPP
+
+#include <boost/type_traits/is_const.hpp>
+#include <boost/mpl/if.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace point_iterator
+{
+
+
+template <typename Geometry>
+struct value_type
+{
+ typedef typename boost::mpl::if_c
+ <
+ !boost::is_const<Geometry>::type::value,
+ typename geometry::point_type<Geometry>::type,
+ typename geometry::point_type<Geometry>::type const
+ >::type type;
+};
+
+
+}} // namespace detail::point_iterator
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_VALUE_TYPE_HPP
diff --git a/3party/boost/boost/geometry/iterators/detail/segment_iterator/iterator_type.hpp b/3party/boost/boost/geometry/iterators/detail/segment_iterator/iterator_type.hpp
new file mode 100644
index 0000000000..57a524e7e4
--- /dev/null
+++ b/3party/boost/boost/geometry/iterators/detail/segment_iterator/iterator_type.hpp
@@ -0,0 +1,153 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_ITERATOR_TYPE_HPP
+#define BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_ITERATOR_TYPE_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/interior_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/iterators/concatenate_iterator.hpp>
+#include <boost/geometry/iterators/flatten_iterator.hpp>
+#include <boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp>
+
+#include <boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp>
+#include <boost/geometry/iterators/detail/segment_iterator/value_type.hpp>
+
+#include <boost/geometry/iterators/dispatch/segment_iterator.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace segment_iterator
+{
+
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct iterator_type
+ : not_implemented<Geometry>
+{};
+
+
+template <typename Linestring>
+struct iterator_type<Linestring, linestring_tag>
+{
+ typedef range_segment_iterator
+ <
+ Linestring, typename value_type<Linestring>::type
+ > type;
+};
+
+
+template <typename Ring>
+struct iterator_type<Ring, ring_tag>
+{
+ typedef range_segment_iterator
+ <
+ Ring, typename value_type<Ring>::type
+ > type;
+};
+
+
+template <typename Polygon>
+class iterator_type<Polygon, polygon_tag>
+{
+private:
+ typedef typename detail::point_iterator::inner_range_type
+ <
+ Polygon
+ >::type inner_range;
+
+public:
+ typedef concatenate_iterator
+ <
+ range_segment_iterator
+ <
+ inner_range,
+ typename value_type<Polygon>::type
+ >,
+ flatten_iterator
+ <
+ typename boost::range_iterator
+ <
+ typename geometry::interior_type<Polygon>::type
+ >::type,
+ typename iterator_type<inner_range>::type,
+ typename value_type<Polygon>::type,
+ dispatch::segments_begin<inner_range>,
+ dispatch::segments_end<inner_range>,
+ typename value_type<Polygon>::type
+ >,
+ typename value_type<Polygon>::type,
+ typename value_type<Polygon>::type
+ > type;
+};
+
+
+template <typename MultiLinestring>
+class iterator_type<MultiLinestring, multi_linestring_tag>
+{
+private:
+ typedef typename detail::point_iterator::inner_range_type
+ <
+ MultiLinestring
+ >::type inner_range;
+
+public:
+ typedef flatten_iterator
+ <
+ typename boost::range_iterator<MultiLinestring>::type,
+ typename iterator_type<inner_range>::type,
+ typename value_type<MultiLinestring>::type,
+ dispatch::segments_begin<inner_range>,
+ dispatch::segments_end<inner_range>,
+ typename value_type<MultiLinestring>::type
+ > type;
+};
+
+
+template <typename MultiPolygon>
+class iterator_type<MultiPolygon, multi_polygon_tag>
+{
+private:
+ typedef typename detail::point_iterator::inner_range_type
+ <
+ MultiPolygon
+ >::type inner_range;
+public:
+ typedef flatten_iterator
+ <
+ typename boost::range_iterator<MultiPolygon>::type,
+ typename iterator_type<inner_range>::type,
+ typename value_type<MultiPolygon>::type,
+ dispatch::segments_begin<inner_range>,
+ dispatch::segments_end<inner_range>,
+ typename value_type<MultiPolygon>::type
+ > type;
+};
+
+
+
+}} // namespace detail::segment_iterator
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_ITERATOR_TYPE_HPP
diff --git a/3party/boost/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp b/3party/boost/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp
new file mode 100644
index 0000000000..e65b12b459
--- /dev/null
+++ b/3party/boost/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp
@@ -0,0 +1,215 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_RANGE_SEGMENT_ITERATOR_HPP
+#define BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_RANGE_SEGMENT_ITERATOR_HPP
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/iterators/closing_iterator.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace segment_iterator
+{
+
+
+template <typename Range, closure_selector Closure = closure<Range>::value>
+struct range_iterator_type
+{
+ typedef typename boost::range_iterator<Range>::type type;
+};
+
+template <typename Range>
+struct range_iterator_type<Range, open>
+{
+ typedef closing_iterator<Range> type;
+};
+
+
+
+template <typename Range, closure_selector Closure = closure<Range>::value>
+struct range_iterator_begin
+{
+ static inline typename range_iterator_type<Range, Closure>::type
+ apply(Range& range)
+ {
+ return boost::begin(range);
+ }
+};
+
+template <typename Range>
+struct range_iterator_begin<Range, open>
+{
+ static inline typename range_iterator_type<Range, open>::type
+ apply(Range& range)
+ {
+ return closing_iterator<Range>(range);
+ }
+};
+
+
+
+template <typename Range, closure_selector Closure = closure<Range>::value>
+struct range_iterator_end
+{
+ static inline typename range_iterator_type<Range, Closure>::type
+ apply(Range& range)
+ {
+ return boost::end(range);
+ }
+};
+
+template <typename Range>
+struct range_iterator_end<Range, open>
+{
+ static inline typename range_iterator_type<Range, open>::type
+ apply(Range& range)
+ {
+ return closing_iterator<Range>(range, true);
+ }
+};
+
+
+
+
+
+
+template <typename Range, typename Value, typename Reference = Value>
+class range_segment_iterator
+ : public boost::iterator_facade
+ <
+ range_segment_iterator<Range, Value, Reference>,
+ Value,
+ boost::bidirectional_traversal_tag,
+ Reference
+ >
+{
+ static inline bool has_less_than_two_elements(Range const& r)
+ {
+ return boost::size(r) < ((closure<Range>::value == open) ? 1u : 2u);
+ }
+
+public:
+ typedef typename range_iterator_type<Range>::type iterator_type;
+
+ // default constructor
+ range_segment_iterator()
+ : m_it(), m_has_less_than_two_elements(false)
+ {}
+
+ // for begin
+ range_segment_iterator(Range& r)
+ : m_it(range_iterator_begin<Range>::apply(r))
+ , m_has_less_than_two_elements(has_less_than_two_elements(r))
+ {}
+
+ // for end
+ range_segment_iterator(Range& r, bool)
+ : m_it(range_iterator_end<Range>::apply(r))
+ , m_has_less_than_two_elements(has_less_than_two_elements(r))
+ {
+ if (! m_has_less_than_two_elements)
+ {
+ // the range consists of at least two items
+ --m_it;
+ }
+ }
+
+ template
+ <
+ typename OtherRange,
+ typename OtherValue,
+ typename OtherReference
+ >
+ range_segment_iterator(range_segment_iterator
+ <
+ OtherRange,
+ OtherValue,
+ OtherReference
+ > const& other)
+ : m_it(other.m_it)
+ {
+ typedef typename range_segment_iterator
+ <
+ OtherRange, OtherValue, OtherReference
+ >::iterator_type other_iterator_type;
+
+ static const bool are_conv
+ = boost::is_convertible<other_iterator_type, iterator_type>::value;
+
+ BOOST_MPL_ASSERT_MSG((are_conv), NOT_CONVERTIBLE, (types<OtherRange>));
+ }
+
+private:
+ friend class boost::iterator_core_access;
+
+ template <typename Rng, typename V, typename R>
+ friend class range_segment_iterator;
+
+ inline Reference dereference() const
+ {
+ if (m_has_less_than_two_elements)
+ {
+ return Reference(*m_it, *m_it);
+ }
+
+ iterator_type next(m_it);
+ ++next;
+ return Reference(*m_it, *next);
+ }
+
+ template
+ <
+ typename OtherRange,
+ typename OtherValue,
+ typename OtherReference
+ >
+ inline bool equal(range_segment_iterator
+ <
+ OtherRange,
+ OtherValue,
+ OtherReference
+ > const& other) const
+ {
+ return m_it == other.m_it;
+ }
+
+ inline void increment()
+ {
+ ++m_it;
+ }
+
+ inline void decrement()
+ {
+ --m_it;
+ }
+
+private:
+ iterator_type m_it;
+ bool m_has_less_than_two_elements;
+};
+
+
+}} // namespace detail::segment_iterator
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_RANGE_SEGMENT_ITERATOR_HPP
diff --git a/3party/boost/boost/geometry/iterators/detail/segment_iterator/value_type.hpp b/3party/boost/boost/geometry/iterators/detail/segment_iterator/value_type.hpp
new file mode 100644
index 0000000000..ff3267c884
--- /dev/null
+++ b/3party/boost/boost/geometry/iterators/detail/segment_iterator/value_type.hpp
@@ -0,0 +1,71 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_VALUE_TYPE_HPP
+#define BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_VALUE_TYPE_HPP
+
+#include <iterator>
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_reference.hpp>
+
+#include <boost/geometry/iterators/point_iterator.hpp>
+#include <boost/geometry/util/bare_type.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/geometries/pointing_segment.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace segment_iterator
+{
+
+template <typename Geometry>
+struct value_type
+{
+ typedef typename std::iterator_traits
+ <
+ geometry::point_iterator<Geometry>
+ >::reference point_iterator_reference_type;
+
+ typedef typename detail::point_iterator::value_type
+ <
+ Geometry
+ >::type point_iterator_value_type;
+
+ // If the reference type of the point iterator is not really a
+ // reference, then dereferencing a point iterator would create
+ // a temporary object.
+ // In this case using a pointing_segment to represent the
+ // dereferenced value of the segment iterator cannot be used, as
+ // it would store pointers to temporary objects. Instead we use a
+ // segment, which does a full copy of the temporary objects
+ // returned by the point iterator.
+ typedef typename boost::mpl::if_
+ <
+ boost::is_reference<point_iterator_reference_type>,
+ geometry::model::pointing_segment<point_iterator_value_type>,
+ geometry::model::segment
+ <
+ typename geometry::util::bare_type
+ <
+ point_iterator_value_type
+ >::type
+ >
+ >::type type;
+};
+
+}} // namespace detail::segment_iterator
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_VALUE_TYPE_HPP
diff --git a/3party/boost/boost/geometry/iterators/dispatch/point_iterator_type.hpp b/3party/boost/boost/geometry/iterators/dispatch/segment_iterator.hpp
index 02c40acae0..0c0a1b09a7 100644
--- a/3party/boost/boost/geometry/iterators/dispatch/point_iterator_type.hpp
+++ b/3party/boost/boost/geometry/iterators/dispatch/segment_iterator.hpp
@@ -7,8 +7,8 @@
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
-#ifndef BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP
-#define BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP
+#ifndef BOOST_GEOMETRY_ITERATORS_DISPATCH_SEGMENT_ITERATOR_HPP
+#define BOOST_GEOMETRY_ITERATORS_DISPATCH_SEGMENT_ITERATOR_HPP
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
@@ -21,8 +21,18 @@ namespace boost { namespace geometry
namespace dispatch
{
+
+// dispatch for segments_begin
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct segments_begin
+ : not_implemented<Geometry>
+{};
+
+
+
+// dispatch for segments_end
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
-struct point_iterator_type
+struct segments_end
: not_implemented<Geometry>
{};
@@ -34,4 +44,4 @@ struct point_iterator_type
}} // namespace boost::geometry
-#endif // BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP
+#endif // BOOST_GEOMETRY_ITERATORS_DISPATCH_SEGMENT_ITERATOR_HPP
diff --git a/3party/boost/boost/geometry/iterators/ever_circling_iterator.hpp b/3party/boost/boost/geometry/iterators/ever_circling_iterator.hpp
index 50b20480cd..cfb588b79f 100644
--- a/3party/boost/boost/geometry/iterators/ever_circling_iterator.hpp
+++ b/3party/boost/boost/geometry/iterators/ever_circling_iterator.hpp
@@ -119,15 +119,6 @@ struct ever_circling_range_iterator
, 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:
diff --git a/3party/boost/boost/geometry/iterators/flatten_iterator.hpp b/3party/boost/boost/geometry/iterators/flatten_iterator.hpp
index 42f7555527..5ba7050220 100644
--- a/3party/boost/boost/geometry/iterators/flatten_iterator.hpp
+++ b/3party/boost/boost/geometry/iterators/flatten_iterator.hpp
@@ -10,13 +10,13 @@
#ifndef BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
+#include <boost/geometry/core/assert.hpp>
namespace boost { namespace geometry
{
@@ -29,7 +29,8 @@ template
typename InnerIterator,
typename Value,
typename AccessInnerBegin,
- typename AccessInnerEnd
+ typename AccessInnerEnd,
+ typename Reference = Value&
>
class flatten_iterator
: public boost::iterator_facade
@@ -40,9 +41,12 @@ class flatten_iterator
InnerIterator,
Value,
AccessInnerBegin,
- AccessInnerEnd>,
+ AccessInnerEnd,
+ Reference
+ >,
Value,
- boost::bidirectional_traversal_tag
+ boost::bidirectional_traversal_tag,
+ Reference
>
{
private:
@@ -72,7 +76,8 @@ public:
<
typename OtherOuterIterator, typename OtherInnerIterator,
typename OtherValue,
- typename OtherAccessInnerBegin, typename OtherAccessInnerEnd
+ typename OtherAccessInnerBegin, typename OtherAccessInnerEnd,
+ typename OtherReference
>
flatten_iterator(flatten_iterator
<
@@ -80,7 +85,8 @@ public:
OtherInnerIterator,
OtherValue,
OtherAccessInnerBegin,
- OtherAccessInnerEnd
+ OtherAccessInnerEnd,
+ OtherReference
> const& other)
: m_outer_it(other.m_outer_it),
m_outer_end(other.m_outer_end),
@@ -101,40 +107,15 @@ public:
(types<OtherOuterIterator, OtherInnerIterator>));
}
- template
- <
- typename OtherOuterIterator,
- typename OtherInnerIterator,
- typename OtherValue,
- typename OtherAccessInnerBegin,
- typename OtherAccessInnerEnd
- >
- flatten_iterator operator=(flatten_iterator
- <
- OtherOuterIterator,
- OtherInnerIterator,
- OtherValue,
- OtherAccessInnerBegin,
- OtherAccessInnerEnd
- > const& other)
+ flatten_iterator& operator=(flatten_iterator const& other)
{
- static const bool are_conv
- = boost::is_convertible
- <
- OtherOuterIterator, OuterIterator
- >::value
- && boost::is_convertible
- <
- OtherInnerIterator, InnerIterator
- >::value;
-
- BOOST_MPL_ASSERT_MSG((are_conv),
- NOT_CONVERTIBLE,
- (types<OtherOuterIterator, OtherInnerIterator>));
-
m_outer_it = other.m_outer_it;
m_outer_end = other.m_outer_end;
- m_inner_it = other.m_inner_it;
+ // avoid assigning an iterator having singular value
+ if ( other.m_outer_it != other.m_outer_end )
+ {
+ m_inner_it = other.m_inner_it;
+ }
return *this;
}
@@ -147,14 +128,15 @@ private:
typename Inner,
typename V,
typename InnerBegin,
- typename InnerEnd
+ typename InnerEnd,
+ typename R
>
friend class flatten_iterator;
static inline bool empty(OuterIterator outer_it)
{
- return
- AccessInnerBegin::apply(*outer_it) == AccessInnerEnd::apply(*outer_it);
+ return AccessInnerBegin::apply(*outer_it)
+ == AccessInnerEnd::apply(*outer_it);
}
inline void advance_through_empty()
@@ -170,10 +152,10 @@ private:
}
}
- inline Value& dereference() const
+ inline Reference dereference() const
{
- BOOST_ASSERT( m_outer_it != m_outer_end );
- BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
+ BOOST_GEOMETRY_ASSERT( m_outer_it != m_outer_end );
+ BOOST_GEOMETRY_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
return *m_inner_it;
}
@@ -184,7 +166,8 @@ private:
typename OtherInnerIterator,
typename OtherValue,
typename OtherAccessInnerBegin,
- typename OtherAccessInnerEnd
+ typename OtherAccessInnerEnd,
+ typename OtherReference
>
inline bool equal(flatten_iterator
<
@@ -192,7 +175,8 @@ private:
OtherInnerIterator,
OtherValue,
OtherAccessInnerBegin,
- OtherAccessInnerEnd
+ OtherAccessInnerEnd,
+ OtherReference
> const& other) const
{
if ( m_outer_it != other.m_outer_it )
@@ -210,8 +194,8 @@ private:
inline void increment()
{
- BOOST_ASSERT( m_outer_it != m_outer_end );
- BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
+ BOOST_GEOMETRY_ASSERT( m_outer_it != m_outer_end );
+ BOOST_GEOMETRY_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
++m_inner_it;
if ( m_inner_it == AccessInnerEnd::apply(*m_outer_it) )
@@ -231,12 +215,9 @@ private:
--m_outer_it;
}
while ( empty(m_outer_it) );
- m_inner_it = --AccessInnerEnd::apply(*m_outer_it);
- }
- else
- {
- --m_inner_it;
- }
+ m_inner_it = AccessInnerEnd::apply(*m_outer_it);
+ }
+ --m_inner_it;
}
};
diff --git a/3party/boost/boost/geometry/iterators/point_iterator.hpp b/3party/boost/boost/geometry/iterators/point_iterator.hpp
index bfe0065d4a..5ee0e54917 100644
--- a/3party/boost/boost/geometry/iterators/point_iterator.hpp
+++ b/3party/boost/boost/geometry/iterators/point_iterator.hpp
@@ -10,7 +10,7 @@
#ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
-#include <boost/assert.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/range.hpp>
@@ -20,7 +20,7 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/iterators/dispatch/point_iterator.hpp>
-#include <boost/geometry/iterators/point_iterator_type.hpp>
+#include <boost/geometry/iterators/detail/point_iterator/iterator_type.hpp>
namespace boost { namespace geometry
@@ -38,7 +38,10 @@ namespace dispatch
template <typename Linestring>
struct points_begin<Linestring, linestring_tag>
{
- static inline typename point_iterator_type<Linestring>::type
+ static inline typename detail::point_iterator::iterator_type
+ <
+ Linestring
+ >::type
apply(Linestring& linestring)
{
return boost::begin(linestring);
@@ -49,7 +52,7 @@ struct points_begin<Linestring, linestring_tag>
template <typename Ring>
struct points_begin<Ring, ring_tag>
{
- static inline typename point_iterator_type<Ring>::type
+ static inline typename detail::point_iterator::iterator_type<Ring>::type
apply(Ring& ring)
{
return boost::begin(ring);
@@ -60,7 +63,10 @@ struct points_begin<Ring, ring_tag>
template <typename Polygon>
struct points_begin<Polygon, polygon_tag>
{
- typedef typename point_iterator_type<Polygon>::type return_type;
+ typedef typename detail::point_iterator::iterator_type
+ <
+ Polygon
+ >::type return_type;
static inline return_type apply(Polygon& polygon)
{
@@ -83,7 +89,10 @@ struct points_begin<Polygon, polygon_tag>
template <typename MultiPoint>
struct points_begin<MultiPoint, multi_point_tag>
{
- static inline typename point_iterator_type<MultiPoint>::type
+ static inline typename detail::point_iterator::iterator_type
+ <
+ MultiPoint
+ >::type
apply(MultiPoint& multipoint)
{
return boost::begin(multipoint);
@@ -94,13 +103,15 @@ struct points_begin<MultiPoint, multi_point_tag>
template <typename MultiLinestring>
struct points_begin<MultiLinestring, multi_linestring_tag>
{
- static inline typename point_iterator_type<MultiLinestring>::type
- apply(MultiLinestring& multilinestring)
+ typedef typename detail::point_iterator::iterator_type
+ <
+ MultiLinestring
+ >::type return_type;
+
+ static inline return_type apply(MultiLinestring& multilinestring)
{
- return typename point_iterator_type
- <
- MultiLinestring
- >::type(boost::begin(multilinestring), boost::end(multilinestring));
+ return return_type(boost::begin(multilinestring),
+ boost::end(multilinestring));
}
};
@@ -108,13 +119,15 @@ struct points_begin<MultiLinestring, multi_linestring_tag>
template <typename MultiPolygon>
struct points_begin<MultiPolygon, multi_polygon_tag>
{
- static inline typename point_iterator_type<MultiPolygon>::type
- apply(MultiPolygon& multipolygon)
+ typedef typename detail::point_iterator::iterator_type
+ <
+ MultiPolygon
+ >::type return_type;
+
+ static inline return_type apply(MultiPolygon& multipolygon)
{
- return typename point_iterator_type
- <
- MultiPolygon
- >::type(boost::begin(multipolygon), boost::end(multipolygon));
+ return return_type(boost::begin(multipolygon),
+ boost::end(multipolygon));
}
};
@@ -136,7 +149,10 @@ namespace dispatch
template <typename Linestring>
struct points_end<Linestring, linestring_tag>
{
- static inline typename point_iterator_type<Linestring>::type
+ static inline typename detail::point_iterator::iterator_type
+ <
+ Linestring
+ >::type
apply(Linestring& linestring)
{
return boost::end(linestring);
@@ -147,7 +163,7 @@ struct points_end<Linestring, linestring_tag>
template <typename Ring>
struct points_end<Ring, ring_tag>
{
- static inline typename point_iterator_type<Ring>::type
+ static inline typename detail::point_iterator::iterator_type<Ring>::type
apply(Ring& ring)
{
return boost::end(ring);
@@ -158,7 +174,10 @@ struct points_end<Ring, ring_tag>
template <typename Polygon>
struct points_end<Polygon, polygon_tag>
{
- typedef typename point_iterator_type<Polygon>::type return_type;
+ typedef typename detail::point_iterator::iterator_type
+ <
+ Polygon
+ >::type return_type;
static inline return_type apply(Polygon& polygon)
{
@@ -178,7 +197,10 @@ struct points_end<Polygon, polygon_tag>
template <typename MultiPoint>
struct points_end<MultiPoint, multi_point_tag>
{
- static inline typename point_iterator_type<MultiPoint>::type
+ static inline typename detail::point_iterator::iterator_type
+ <
+ MultiPoint
+ >::type
apply(MultiPoint& multipoint)
{
return boost::end(multipoint);
@@ -189,13 +211,14 @@ struct points_end<MultiPoint, multi_point_tag>
template <typename MultiLinestring>
struct points_end<MultiLinestring, multi_linestring_tag>
{
- static inline typename point_iterator_type<MultiLinestring>::type
- apply(MultiLinestring& multilinestring)
+ typedef typename detail::point_iterator::iterator_type
+ <
+ MultiLinestring
+ >::type return_type;
+
+ static inline return_type apply(MultiLinestring& multilinestring)
{
- return typename point_iterator_type
- <
- MultiLinestring
- >::type(boost::end(multilinestring));
+ return return_type(boost::end(multilinestring));
}
};
@@ -203,13 +226,14 @@ struct points_end<MultiLinestring, multi_linestring_tag>
template <typename MultiPolygon>
struct points_end<MultiPolygon, multi_polygon_tag>
{
- static inline typename point_iterator_type<MultiPolygon>::type
- apply(MultiPolygon& multipolygon)
+ typedef typename detail::point_iterator::iterator_type
+ <
+ MultiPolygon
+ >::type return_type;
+
+ static inline return_type apply(MultiPolygon& multipolygon)
{
- return typename point_iterator_type
- <
- MultiPolygon
- >::type(boost::end(multipolygon));
+ return return_type(boost::end(multipolygon));
}
};
@@ -221,38 +245,37 @@ struct points_end<MultiPolygon, multi_polygon_tag>
// MK:: need to add doc here
template <typename Geometry>
class point_iterator
- : public dispatch::point_iterator_type<Geometry>::type
+ : public boost::iterator_adaptor
+ <
+ point_iterator<Geometry>,
+ typename detail::point_iterator::iterator_type<Geometry>::type
+ >
{
private:
- typedef typename dispatch::point_iterator_type<Geometry>::type base;
-
- base* base_ptr()
- {
- return this;
- }
-
- base const* base_ptr() const
- {
- return this;
- }
-
template <typename OtherGeometry> friend class point_iterator;
template <typename G> friend inline point_iterator<G> points_begin(G&);
template <typename G> friend inline point_iterator<G> points_end(G&);
- point_iterator(base const& base_it) : base(base_it) {}
+ inline point_iterator(typename point_iterator::base_type const& base_it)
+ : point_iterator::iterator_adaptor_(base_it) {}
public:
- point_iterator() {}
+ inline point_iterator() {}
template <typename OtherGeometry>
- point_iterator(point_iterator<OtherGeometry> const& other)
- : base(*other.base_ptr())
+ inline point_iterator(point_iterator<OtherGeometry> const& other)
+ : point_iterator::iterator_adaptor_(other.base())
{
static const bool is_conv
= boost::is_convertible<
- typename dispatch::point_iterator_type<OtherGeometry>::type,
- typename dispatch::point_iterator_type<Geometry>::type
+ typename detail::point_iterator::iterator_type
+ <
+ OtherGeometry
+ >::type,
+ typename detail::point_iterator::iterator_type
+ <
+ Geometry
+ >::type
>::value;
BOOST_MPL_ASSERT_MSG((is_conv),
diff --git a/3party/boost/boost/geometry/iterators/point_iterator_type.hpp b/3party/boost/boost/geometry/iterators/point_iterator_type.hpp
deleted file mode 100644
index 4991b27187..0000000000
--- a/3party/boost/boost/geometry/iterators/point_iterator_type.hpp
+++ /dev/null
@@ -1,207 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2014, Oracle and/or its affiliates.
-
-// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
-
-// Licensed under the Boost Software License version 1.0.
-// http://www.boost.org/users/license.html
-
-#ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP
-#define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP
-
-#include <boost/geometry/iterators/dispatch/point_iterator_type.hpp>
-#include <boost/geometry/iterators/dispatch/point_iterator.hpp>
-
-#include <boost/range.hpp>
-#include <boost/type_traits/is_const.hpp>
-#include <boost/mpl/if.hpp>
-
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/ring_type.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/iterators/flatten_iterator.hpp>
-#include <boost/geometry/iterators/concatenate_iterator.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail_dispatch
-{
-
-
-template <typename Geometry>
-struct point_iterator_value_type
-{
- typedef typename boost::mpl::if_c
- <
- !boost::is_const<Geometry>::type::value,
- typename geometry::point_type<Geometry>::type,
- typename geometry::point_type<Geometry>::type const
- >::type type;
-};
-
-
-
-
-template
-<
- typename Geometry,
- typename Tag = typename tag<Geometry>::type
->
-struct point_iterator_inner_range_type
-{
- typedef typename boost::mpl::if_c
- <
- !boost::is_const<Geometry>::type::value,
- typename boost::range_value<Geometry>::type,
- typename boost::range_value<Geometry>::type const
- >::type type;
-};
-
-
-template <typename Polygon>
-struct point_iterator_inner_range_type<Polygon, polygon_tag>
-{
- typedef typename boost::mpl::if_c
- <
- !boost::is_const<Polygon>::type::value,
- typename geometry::ring_type<Polygon>::type,
- typename geometry::ring_type<Polygon>::type const
- >::type type;
-};
-
-
-
-} // namespace detail_dispatch
-#endif // DOXYGEN_NO_DETAIL
-
-
-
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-template <typename Linestring>
-struct point_iterator_type<Linestring, linestring_tag>
-{
- typedef typename boost::range_iterator<Linestring>::type type;
-};
-
-
-template <typename Ring>
-struct point_iterator_type<Ring, ring_tag>
-{
- typedef typename boost::range_iterator<Ring>::type type;
-};
-
-
-template <typename Polygon>
-class point_iterator_type<Polygon, polygon_tag>
-{
-private:
- typedef typename detail_dispatch::point_iterator_inner_range_type
- <
- Polygon
- >::type inner_range;
-
-public:
- typedef concatenate_iterator
- <
- typename boost::range_iterator<inner_range>::type,
- flatten_iterator
- <
- typename boost::range_iterator
- <
- typename geometry::interior_type<Polygon>::type
- >::type,
- typename dispatch::point_iterator_type
- <
- inner_range
- >::type,
- typename detail_dispatch::point_iterator_value_type
- <
- Polygon
- >::type,
- dispatch::points_begin<inner_range>,
- dispatch::points_end<inner_range>
- >,
- typename detail_dispatch::point_iterator_value_type<Polygon>::type
- > type;
-};
-
-
-template <typename MultiPoint>
-struct point_iterator_type<MultiPoint, multi_point_tag>
-{
- typedef typename boost::range_iterator<MultiPoint>::type type;
-};
-
-
-template <typename MultiLinestring>
-class point_iterator_type<MultiLinestring, multi_linestring_tag>
-{
-private:
- typedef typename detail_dispatch::point_iterator_inner_range_type
- <
- MultiLinestring
- >::type inner_range;
-
-public:
- typedef flatten_iterator
- <
- typename boost::range_iterator<MultiLinestring>::type,
- typename dispatch::point_iterator_type<inner_range>::type,
- typename detail_dispatch::point_iterator_value_type
- <
- MultiLinestring
- >::type,
- dispatch::points_begin<inner_range>,
- dispatch::points_end<inner_range>
- > type;
-};
-
-
-template <typename MultiPolygon>
-class point_iterator_type<MultiPolygon, multi_polygon_tag>
-{
-private:
- typedef typename detail_dispatch::point_iterator_inner_range_type
- <
- MultiPolygon
- >::type inner_range;
-
-public:
- typedef flatten_iterator
- <
- typename boost::range_iterator<MultiPolygon>::type,
- typename dispatch::point_iterator_type<inner_range>::type,
- typename detail_dispatch::point_iterator_value_type
- <
- MultiPolygon
- >::type,
- dispatch::points_begin<inner_range>,
- dispatch::points_end<inner_range>
- > type;
-};
-
-
-
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-}} // namespace boost::geometry
-
-
-#endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP
diff --git a/3party/boost/boost/geometry/iterators/point_reverse_iterator.hpp b/3party/boost/boost/geometry/iterators/point_reverse_iterator.hpp
index 5cce66795a..b464c5f22a 100644
--- a/3party/boost/boost/geometry/iterators/point_reverse_iterator.hpp
+++ b/3party/boost/boost/geometry/iterators/point_reverse_iterator.hpp
@@ -27,17 +27,7 @@ class point_reverse_iterator
: public std::reverse_iterator<point_iterator<Geometry> >
{
private:
- typedef std::reverse_iterator<point_iterator<Geometry> > base;
-
- base* base_ptr()
- {
- return this;
- }
-
- base const* base_ptr() const
- {
- return this;
- }
+ typedef std::reverse_iterator<point_iterator<Geometry> > base_type;
template <typename OtherGeometry> friend class point_reverse_iterator;
template <typename G>
@@ -46,14 +36,16 @@ private:
template <typename G>
friend inline point_reverse_iterator<G> points_rend(G&);
- point_reverse_iterator(base const& base_it) : base(base_it) {}
+ inline point_reverse_iterator(base_type const& base_it)
+ : base_type(base_it) {}
public:
- point_reverse_iterator() {}
+ inline point_reverse_iterator() {}
template <typename OtherGeometry>
+ inline
point_reverse_iterator(point_reverse_iterator<OtherGeometry> const& other)
- : base(*other.base_ptr())
+ : base_type(other.base())
{
static const bool is_conv = boost::is_convertible
<
diff --git a/3party/boost/boost/geometry/iterators/segment_iterator.hpp b/3party/boost/boost/geometry/iterators/segment_iterator.hpp
new file mode 100644
index 0000000000..71aff39c43
--- /dev/null
+++ b/3party/boost/boost/geometry/iterators/segment_iterator.hpp
@@ -0,0 +1,353 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP
+#define BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp>
+#include <boost/geometry/iterators/detail/segment_iterator/iterator_type.hpp>
+
+#include <boost/geometry/iterators/dispatch/segment_iterator.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// specializations for segments_begin
+
+
+template <typename Linestring>
+struct segments_begin<Linestring, linestring_tag>
+{
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ Linestring
+ >::type return_type;
+
+ static inline return_type apply(Linestring& linestring)
+ {
+ return return_type(linestring);
+ }
+};
+
+
+template <typename Ring>
+struct segments_begin<Ring, ring_tag>
+{
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ Ring
+ >::type return_type;
+
+ static inline return_type apply(Ring& ring)
+ {
+ return return_type(ring);
+ }
+};
+
+
+template <typename Polygon>
+struct segments_begin<Polygon, polygon_tag>
+{
+ typedef typename detail::point_iterator::inner_range_type
+ <
+ Polygon
+ >::type inner_range;
+
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ Polygon
+ >::type return_type;
+
+ static inline return_type apply(Polygon& polygon)
+ {
+ typedef typename return_type::second_iterator_type flatten_iterator;
+
+ return return_type
+ (segments_begin
+ <
+ inner_range
+ >::apply(geometry::exterior_ring(polygon)),
+ segments_end
+ <
+ inner_range
+ >::apply(geometry::exterior_ring(polygon)),
+ flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
+ boost::end(geometry::interior_rings(polygon))
+ ),
+ flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
+ boost::end(geometry::interior_rings(polygon))
+ )
+ );
+ }
+};
+
+
+template <typename MultiLinestring>
+struct segments_begin<MultiLinestring, multi_linestring_tag>
+{
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ MultiLinestring
+ >::type return_type;
+
+ static inline return_type apply(MultiLinestring& multilinestring)
+ {
+ return return_type(boost::begin(multilinestring),
+ boost::end(multilinestring));
+ }
+};
+
+
+template <typename MultiPolygon>
+struct segments_begin<MultiPolygon, multi_polygon_tag>
+{
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ MultiPolygon
+ >::type return_type;
+
+ static inline return_type apply(MultiPolygon& multipolygon)
+ {
+ return return_type(boost::begin(multipolygon),
+ boost::end(multipolygon));
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// specializations for segments_end
+
+
+template <typename Linestring>
+struct segments_end<Linestring, linestring_tag>
+{
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ Linestring
+ >::type return_type;
+
+ static inline return_type apply(Linestring& linestring)
+ {
+ return return_type(linestring, true);
+ }
+};
+
+
+template <typename Ring>
+struct segments_end<Ring, ring_tag>
+{
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ Ring
+ >::type return_type;
+
+ static inline return_type apply(Ring& ring)
+ {
+ return return_type(ring, true);
+ }
+};
+
+
+template <typename Polygon>
+struct segments_end<Polygon, polygon_tag>
+{
+ typedef typename detail::point_iterator::inner_range_type
+ <
+ Polygon
+ >::type inner_range;
+
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ Polygon
+ >::type return_type;
+
+ static inline return_type apply(Polygon& polygon)
+ {
+ typedef typename return_type::second_iterator_type flatten_iterator;
+
+ return return_type
+ (segments_end
+ <
+ inner_range
+ >::apply(geometry::exterior_ring(polygon)),
+ flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
+ boost::end(geometry::interior_rings(polygon))
+ ),
+ flatten_iterator( boost::end(geometry::interior_rings(polygon)) )
+ );
+ }
+};
+
+
+template <typename MultiLinestring>
+struct segments_end<MultiLinestring, multi_linestring_tag>
+{
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ MultiLinestring
+ >::type return_type;
+
+ static inline return_type apply(MultiLinestring& multilinestring)
+ {
+ return return_type(boost::end(multilinestring));
+ }
+};
+
+
+template <typename MultiPolygon>
+struct segments_end<MultiPolygon, multi_polygon_tag>
+{
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ MultiPolygon
+ >::type return_type;
+
+ static inline return_type apply(MultiPolygon& multipolygon)
+ {
+ return return_type(boost::end(multipolygon));
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+// MK:: need to add doc here
+template <typename Geometry>
+class segment_iterator
+ : public detail::segment_iterator::iterator_type<Geometry>::type
+{
+private:
+ typedef typename detail::segment_iterator::iterator_type
+ <
+ Geometry
+ >::type base;
+
+ inline base const* base_ptr() const
+ {
+ return this;
+ }
+
+ template <typename OtherGeometry> friend class segment_iterator;
+
+ template <typename G>
+ friend inline segment_iterator<G const> segments_begin(G const&);
+
+ template <typename G>
+ friend inline segment_iterator<G const> segments_end(G const&);
+
+ inline segment_iterator(base const& base_it) : base(base_it) {}
+
+public:
+ // The following typedef is needed for this iterator to be
+ // bidirectional.
+ // Normally we would not have to define this. However, due to the
+ // fact that the value type of the iterator is not a reference,
+ // the iterator_facade framework (used to define the base class of
+ // this iterator) degrades automatically the iterator's category
+ // to input iterator. With the following typedef we recover the
+ // correct iterator category.
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ inline segment_iterator() {}
+
+ template <typename OtherGeometry>
+ inline segment_iterator(segment_iterator<OtherGeometry> const& other)
+ : base(*other.base_ptr())
+ {
+ static const bool is_conv
+ = boost::is_convertible<
+ typename detail::segment_iterator::iterator_type
+ <
+ OtherGeometry
+ >::type,
+ typename detail::segment_iterator::iterator_type<Geometry>::type
+ >::value;
+
+ BOOST_MPL_ASSERT_MSG((is_conv),
+ NOT_CONVERTIBLE,
+ (segment_iterator<OtherGeometry>));
+ }
+
+ inline segment_iterator& operator++() // prefix
+ {
+ base::operator++();
+ return *this;
+ }
+
+ inline segment_iterator& operator--() // prefix
+ {
+ base::operator--();
+ return *this;
+ }
+
+ inline segment_iterator operator++(int) // postfix
+ {
+ segment_iterator copy(*this);
+ base::operator++();
+ return copy;
+ }
+
+ inline segment_iterator operator--(int) // postfix
+ {
+ segment_iterator copy(*this);
+ base::operator--();
+ return copy;
+ }
+};
+
+
+// MK:: need to add doc here
+template <typename Geometry>
+inline segment_iterator<Geometry const>
+segments_begin(Geometry const& geometry)
+{
+ return dispatch::segments_begin<Geometry const>::apply(geometry);
+}
+
+
+// MK:: need to add doc here
+template <typename Geometry>
+inline segment_iterator<Geometry const>
+segments_end(Geometry const& geometry)
+{
+ return dispatch::segments_end<Geometry const>::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP
diff --git a/3party/boost/boost/geometry/multi/algorithms/append.hpp b/3party/boost/boost/geometry/multi/algorithms/append.hpp
index 2a2596c548..d1589aca84 100644
--- a/3party/boost/boost/geometry/multi/algorithms/append.hpp
+++ b/3party/boost/boost/geometry/multi/algorithms/append.hpp
@@ -8,6 +8,7 @@
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -19,88 +20,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
-#include <boost/geometry/algorithms/append.hpp>
-
-#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/geometries/concepts/check.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace append
-{
-
-
-template <typename MultiGeometry, typename RangeOrPoint>
-struct append_to_multigeometry
-{
- static inline void apply(MultiGeometry& multigeometry,
- RangeOrPoint const& range_or_point,
- int ring_index, int multi_index)
- {
-
- dispatch::append
- <
- typename boost::range_value<MultiGeometry>::type,
- RangeOrPoint
- >::apply(multigeometry[multi_index], range_or_point, ring_index);
- }
-};
-
-
-}} // namespace detail::append
-#endif // DOXYGEN_NO_DETAIL
-
-
-
-#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>
-{};
-
-template <typename MultiGeometry, typename RangeOrPoint>
-struct append_point<multi_linestring_tag, MultiGeometry, RangeOrPoint>
- : detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
-{};
-
-template <typename MultiGeometry, typename RangeOrPoint>
-struct append_range<multi_linestring_tag, MultiGeometry, RangeOrPoint>
- : detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
-{};
-
-template <typename MultiGeometry, typename RangeOrPoint>
-struct append_point<multi_polygon_tag, MultiGeometry, RangeOrPoint>
- : detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
-{};
-
-template <typename MultiGeometry, typename RangeOrPoint>
-struct append_range<multi_polygon_tag, MultiGeometry, RangeOrPoint>
- : detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
-{};
-
-}
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-}} // namespace boost::geometry
+#include <boost/geometry/algorithms/append.hpp>
#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
diff --git a/3party/boost/boost/geometry/multi/algorithms/detail/overlay/select_rings.hpp b/3party/boost/boost/geometry/multi/algorithms/detail/overlay/select_rings.hpp
deleted file mode 100644
index c780c4cd9a..0000000000
--- a/3party/boost/boost/geometry/multi/algorithms/detail/overlay/select_rings.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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/geometry/algorithms/detail/overlay/select_rings.hpp>
-
-
-#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
diff --git a/3party/boost/boost/geometry/multi/algorithms/intersection.hpp b/3party/boost/boost/geometry/multi/algorithms/intersection.hpp
index e0f3592e8f..f434463253 100644
--- a/3party/boost/boost/geometry/multi/algorithms/intersection.hpp
+++ b/3party/boost/boost/geometry/multi/algorithms/intersection.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -9,407 +14,9 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
-#include <boost/geometry/core/closure.hpp>
-#include <boost/geometry/core/geometry_id.hpp>
-#include <boost/geometry/core/is_areal.hpp>
-#include <boost/geometry/core/point_order.hpp>
-#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/geometries/concepts/check.hpp>
-
-// TODO: those headers probably may be removed
-#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
-#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
-#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
-#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
-#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
-#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
-#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
-#include <boost/geometry/multi/algorithms/covered_by.hpp>
-#include <boost/geometry/multi/algorithms/envelope.hpp>
-#include <boost/geometry/multi/algorithms/num_points.hpp>
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace intersection
-{
-
-
-template <typename PointOut>
-struct intersection_multi_linestring_multi_linestring_point
-{
- template
- <
- typename MultiLinestring1, typename MultiLinestring2,
- typename RobustPolicy,
- typename OutputIterator, typename Strategy
- >
- static inline OutputIterator apply(MultiLinestring1 const& ml1,
- MultiLinestring2 const& ml2,
- RobustPolicy const& robust_policy,
- 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<PointOut>
- ::apply(*it1, *it2, robust_policy, out, strategy);
- }
- }
-
- return out;
- }
-};
-
-
-template <typename PointOut>
-struct intersection_linestring_multi_linestring_point
-{
- template
- <
- typename Linestring, typename MultiLinestring,
- typename RobustPolicy,
- typename OutputIterator, typename Strategy
- >
- static inline OutputIterator apply(Linestring const& linestring,
- MultiLinestring const& ml,
- RobustPolicy const& robust_policy,
- 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<PointOut>
- ::apply(linestring, *it, robust_policy, 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
-<
- bool ReverseAreal,
- typename LineStringOut,
- overlay_type OverlayType
->
-struct intersection_of_multi_linestring_with_areal
-{
- template
- <
- typename MultiLinestring, typename Areal,
- typename RobustPolicy,
- typename OutputIterator, typename Strategy
- >
- static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
- RobustPolicy const& robust_policy,
- 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
- <
- ReverseAreal, LineStringOut, OverlayType
- >::apply(*it, areal, robust_policy, out, strategy);
- }
-
- return out;
-
- }
-};
-
-// This one calls the one above with reversed arguments
-template
-<
- bool ReverseAreal,
- typename LineStringOut,
- overlay_type OverlayType
->
-struct intersection_of_areal_with_multi_linestring
-{
- template
- <
- typename Areal, typename MultiLinestring,
- typename RobustPolicy,
- typename OutputIterator, typename Strategy
- >
- static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
- RobustPolicy const& robust_policy,
- OutputIterator out,
- Strategy const& strategy)
- {
- return intersection_of_multi_linestring_with_areal
- <
- ReverseAreal, LineStringOut, OverlayType
- >::apply(ml, areal, robust_policy, out, strategy);
- }
-};
-
-
-
-template <typename LinestringOut>
-struct clip_multi_linestring
-{
- template
- <
- typename MultiLinestring, typename Box,
- typename RobustPolicy,
- typename OutputIterator, typename Strategy
- >
- static inline OutputIterator apply(MultiLinestring const& multi_linestring,
- Box const& box,
- RobustPolicy const& robust_policy,
- 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, robust_policy, out, lb_strategy);
- }
- return out;
- }
-};
-
-
-}} // namespace detail::intersection
-#endif // DOXYGEN_NO_DETAIL
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-// Linear
-template
-<
- typename MultiLinestring1, typename MultiLinestring2,
- typename GeometryOut,
- overlay_type OverlayType,
- bool Reverse1, bool Reverse2, bool ReverseOut
->
-struct intersection_insert
- <
- MultiLinestring1, MultiLinestring2,
- GeometryOut,
- OverlayType,
- Reverse1, Reverse2, ReverseOut,
- multi_linestring_tag, multi_linestring_tag, point_tag,
- false, false, false
- > : detail::intersection::intersection_multi_linestring_multi_linestring_point
- <
- GeometryOut
- >
-{};
-
-
-template
-<
- typename Linestring, typename MultiLinestring,
- typename GeometryOut,
- overlay_type OverlayType,
- bool Reverse1, bool Reverse2, bool ReverseOut
->
-struct intersection_insert
- <
- Linestring, MultiLinestring,
- GeometryOut,
- OverlayType,
- Reverse1, Reverse2, ReverseOut,
- linestring_tag, multi_linestring_tag, point_tag,
- false, false, false
- > : detail::intersection::intersection_linestring_multi_linestring_point
- <
- GeometryOut
- >
-{};
-
-
-template
-<
- typename MultiLinestring, typename Box,
- typename GeometryOut,
- overlay_type OverlayType,
- bool Reverse1, bool Reverse2, bool ReverseOut
->
-struct intersection_insert
- <
- MultiLinestring, Box,
- GeometryOut,
- OverlayType,
- Reverse1, Reverse2, ReverseOut,
- multi_linestring_tag, box_tag, linestring_tag,
- false, true, false
- > : detail::intersection::clip_multi_linestring
- <
- GeometryOut
- >
-{};
-
-
-template
-<
- typename Linestring, typename MultiPolygon,
- typename GeometryOut,
- overlay_type OverlayType,
- bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut
->
-struct intersection_insert
- <
- Linestring, MultiPolygon,
- GeometryOut,
- OverlayType,
- ReverseLinestring, ReverseMultiPolygon, ReverseOut,
- linestring_tag, multi_polygon_tag, linestring_tag,
- false, true, false
- > : detail::intersection::intersection_of_linestring_with_areal
- <
- ReverseMultiPolygon,
- GeometryOut,
- OverlayType
- >
-{};
-
-
-// Derives from areal/mls because runtime arguments are in that order.
-// areal/mls reverses it itself to mls/areal
-template
-<
- typename Polygon, typename MultiLinestring,
- typename GeometryOut,
- overlay_type OverlayType,
- bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut
->
-struct intersection_insert
- <
- Polygon, MultiLinestring,
- GeometryOut,
- OverlayType,
- ReversePolygon, ReverseMultiLinestring, ReverseOut,
- polygon_tag, multi_linestring_tag, linestring_tag,
- true, false, false
- > : detail::intersection::intersection_of_areal_with_multi_linestring
- <
- ReversePolygon,
- GeometryOut,
- OverlayType
- >
-{};
-
-
-template
-<
- typename MultiLinestring, typename Ring,
- typename GeometryOut,
- overlay_type OverlayType,
- bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
->
-struct intersection_insert
- <
- MultiLinestring, Ring,
- GeometryOut,
- OverlayType,
- ReverseMultiLinestring, ReverseRing, ReverseOut,
- multi_linestring_tag, ring_tag, linestring_tag,
- false, true, false
- > : detail::intersection::intersection_of_multi_linestring_with_areal
- <
- ReverseRing,
- GeometryOut,
- OverlayType
- >
-{};
-
-template
-<
- typename MultiLinestring, typename Polygon,
- typename GeometryOut,
- overlay_type OverlayType,
- bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
->
-struct intersection_insert
- <
- MultiLinestring, Polygon,
- GeometryOut,
- OverlayType,
- ReverseMultiLinestring, ReverseRing, ReverseOut,
- multi_linestring_tag, polygon_tag, linestring_tag,
- false, true, false
- > : detail::intersection::intersection_of_multi_linestring_with_areal
- <
- ReverseRing,
- GeometryOut,
- OverlayType
- >
-{};
-
-
-
-template
-<
- typename MultiLinestring, typename MultiPolygon,
- typename GeometryOut,
- overlay_type OverlayType,
- bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut
->
-struct intersection_insert
- <
- MultiLinestring, MultiPolygon,
- GeometryOut,
- OverlayType,
- ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut,
- multi_linestring_tag, multi_polygon_tag, linestring_tag,
- false, true, false
- > : detail::intersection::intersection_of_multi_linestring_with_areal
- <
- ReverseMultiPolygon,
- GeometryOut,
- OverlayType
- >
-{};
-
-
-} // namespace dispatch
-#endif
-
-}} // namespace boost::geometry
-
#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
diff --git a/3party/boost/boost/geometry/multi/algorithms/num_interior_rings.hpp b/3party/boost/boost/geometry/multi/algorithms/num_interior_rings.hpp
index 5b52508b7e..fbaa113aff 100644
--- a/3party/boost/boost/geometry/multi/algorithms/num_interior_rings.hpp
+++ b/3party/boost/boost/geometry/multi/algorithms/num_interior_rings.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -14,48 +19,8 @@
#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/geometries/concepts/check.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<MultiPolygon, multi_polygon_tag>
-{
- 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/3party/boost/boost/geometry/multi/algorithms/num_points.hpp b/3party/boost/boost/geometry/multi/algorithms/num_points.hpp
index ac10ddff41..a736f4254b 100644
--- a/3party/boost/boost/geometry/multi/algorithms/num_points.hpp
+++ b/3party/boost/boost/geometry/multi/algorithms/num_points.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,66 +20,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
-#include <cstddef>
-
-#include <boost/range.hpp>
-#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace num_points
-{
-
-
-struct multi_count
-{
- template <typename MultiGeometry>
- static inline
- std::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<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<Geometry, multi_tag>
- : detail::num_points::multi_count {};
-
-
-} // namespace dispatch
-#endif
-
-
-}} // namespace boost::geometry
-
-
#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
diff --git a/3party/boost/boost/geometry/multi/multi.hpp b/3party/boost/boost/geometry/multi/multi.hpp
index 24e39c3c7c..85d763ee6e 100644
--- a/3party/boost/boost/geometry/multi/multi.hpp
+++ b/3party/boost/boost/geometry/multi/multi.hpp
@@ -1,11 +1,11 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2013.
-// Modifications copyright (c) 2013, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2015.
+// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -17,66 +17,8 @@
#ifndef BOOST_GEOMETRY_MULTI_HPP
#define BOOST_GEOMETRY_MULTI_HPP
-
-#include <boost/geometry/core/closure.hpp>
-#include <boost/geometry/core/geometry_id.hpp>
-#include <boost/geometry/core/interior_rings.hpp>
-#include <boost/geometry/core/is_areal.hpp>
-#include <boost/geometry/core/point_order.hpp>
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/ring_type.hpp>
-#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/core/topological_dimension.hpp>
-
-#include <boost/geometry/algorithms/area.hpp>
-#include <boost/geometry/algorithms/centroid.hpp>
-#include <boost/geometry/algorithms/clear.hpp>
-#include <boost/geometry/algorithms/convert.hpp>
-#include <boost/geometry/algorithms/correct.hpp>
-#include <boost/geometry/algorithms/covered_by.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/for_each.hpp>
-#include <boost/geometry/algorithms/length.hpp>
-#include <boost/geometry/algorithms/num_geometries.hpp>
-#include <boost/geometry/algorithms/perimeter.hpp>
-#include <boost/geometry/algorithms/remove_spikes.hpp>
-#include <boost/geometry/algorithms/reverse.hpp>
-#include <boost/geometry/algorithms/simplify.hpp>
-#include <boost/geometry/algorithms/transform.hpp>
-#include <boost/geometry/algorithms/unique.hpp>
-#include <boost/geometry/algorithms/within.hpp>
-
-#include <boost/geometry/multi/algorithms/append.hpp>
-#include <boost/geometry/multi/algorithms/intersection.hpp>
-#include <boost/geometry/multi/algorithms/num_interior_rings.hpp>
-#include <boost/geometry/multi/algorithms/num_points.hpp>
-
-#include <boost/geometry/algorithms/detail/point_on_border.hpp>
-
-#include <boost/geometry/algorithms/detail/for_each_range.hpp>
-#include <boost/geometry/algorithms/detail/multi_modify_with_predicate.hpp>
-#include <boost/geometry/algorithms/detail/multi_sum.hpp>
-
-#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
-#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
-
-#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
-#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
-#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
-#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
-#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
-#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
-
-#include <boost/geometry/geometries/concepts/check.hpp>
-
-#include <boost/geometry/views/detail/range_type.hpp>
-#include <boost/geometry/strategies/cartesian/centroid_average.hpp>
-
-#include <boost/geometry/io/dsv/write.hpp>
-#include <boost/geometry/io/wkt/wkt.hpp>
-
+// keep this file for now, for backward compatibility
+// functionality-wise, make it equivalent to boost/geometry/geometry.hpp
+#include <boost/geometry/geometry.hpp>
#endif // BOOST_GEOMETRY_MULTI_HPP
diff --git a/3party/boost/boost/geometry/policies/is_valid/default_policy.hpp b/3party/boost/boost/geometry/policies/is_valid/default_policy.hpp
new file mode 100644
index 0000000000..c1bd347e11
--- /dev/null
+++ b/3party/boost/boost/geometry/policies/is_valid/default_policy.hpp
@@ -0,0 +1,59 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_POLICIES_IS_VALID_DEFAULT_POLICY_HPP
+#define BOOST_GEOMETRY_POLICIES_IS_VALID_DEFAULT_POLICY_HPP
+
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+template <bool AllowDuplicates = true, bool AllowSpikes = true>
+class is_valid_default_policy
+{
+protected:
+ static inline bool is_valid(validity_failure_type failure)
+ {
+ return failure == no_failure
+ || (AllowDuplicates && failure == failure_duplicate_points);
+ }
+
+ static inline bool is_valid(validity_failure_type failure, bool is_linear)
+ {
+ return is_valid(failure)
+ || (is_linear && AllowSpikes && failure == failure_spikes);
+ }
+
+public:
+ template <validity_failure_type Failure>
+ static inline bool apply()
+ {
+ return is_valid(Failure);
+ }
+
+ template <validity_failure_type Failure, typename Data>
+ static inline bool apply(Data const&)
+ {
+ return is_valid(Failure);
+ }
+
+ template <validity_failure_type Failure, typename Data1, typename Data2>
+ static inline bool apply(Data1 const& data1, Data2 const&)
+ {
+ return is_valid(Failure, data1);
+ }
+};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_POLICIES_IS_VALID_DEFAULT_POLICY_HPP
diff --git a/3party/boost/boost/geometry/policies/is_valid/failing_reason_policy.hpp b/3party/boost/boost/geometry/policies/is_valid/failing_reason_policy.hpp
new file mode 100644
index 0000000000..b99803bead
--- /dev/null
+++ b/3party/boost/boost/geometry/policies/is_valid/failing_reason_policy.hpp
@@ -0,0 +1,218 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_POLICIES_IS_VALID_FAILING_REASON_POLICY_HPP
+#define BOOST_GEOMETRY_POLICIES_IS_VALID_FAILING_REASON_POLICY_HPP
+
+#include <sstream>
+
+#include <boost/geometry/io/dsv/write.hpp>
+#include <boost/geometry/util/range.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
+#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+inline char const* validity_failure_type_message(validity_failure_type failure)
+{
+ switch (failure)
+ {
+ case no_failure:
+ return "Geometry is valid";
+ case failure_few_points:
+ return "Geometry has too few points";
+ case failure_wrong_topological_dimension:
+ return "Geometry has wrong topological dimension";
+ case failure_not_closed:
+ return "Geometry is defined as closed but is open";
+ case failure_spikes:
+ return "Geometry has spikes";
+ case failure_self_intersections:
+ return "Geometry has invalid self-intersections";
+ case failure_wrong_orientation:
+ return "Geometry has wrong orientation";
+ case failure_interior_rings_outside:
+ return "Geometry has interior rings defined outside the outer boundary";
+ case failure_nested_interior_rings:
+ return "Geometry has nested interior rings";
+ case failure_disconnected_interior:
+ return "Geometry has disconnected interior";
+ case failure_intersecting_interiors:
+ return "Multi-polygon has intersecting interiors";
+ case failure_duplicate_points:
+ return "Geometry has duplicate (consecutive) points";
+ case failure_wrong_corner_order:
+ return "Box has corners in wrong order";
+ default: // to avoid -Wreturn-type warning
+ return "";
+ }
+}
+
+
+template <bool AllowDuplicates = true, bool AllowSpikes = true>
+class failing_reason_policy
+{
+private:
+ static inline
+ validity_failure_type transform_failure_type(validity_failure_type failure)
+ {
+ if (AllowDuplicates && failure == failure_duplicate_points)
+ {
+ return no_failure;
+ }
+ return failure;
+ }
+
+ static inline
+ validity_failure_type transform_failure_type(validity_failure_type failure,
+ bool is_linear)
+ {
+ if (is_linear && AllowSpikes && failure == failure_spikes)
+ {
+ return no_failure;
+ }
+ return transform_failure_type(failure);
+ }
+
+ inline void set_failure_message(validity_failure_type failure)
+ {
+ m_oss.str("");
+ m_oss.clear();
+ m_oss << validity_failure_type_message(failure);
+ }
+
+ template
+ <
+ validity_failure_type Failure,
+ typename Data1,
+ typename Data2 = Data1,
+ typename Dummy = void
+ >
+ struct process_data
+ {
+ static inline void apply(std::ostringstream&, Data1 const&)
+ {
+ }
+
+ static inline void apply(std::ostringstream&,
+ Data1 const&,
+ Data2 const&)
+ {
+ }
+ };
+
+ template <typename SpikePoint>
+ struct process_data<failure_spikes, bool, SpikePoint>
+ {
+ static inline void apply(std::ostringstream& oss,
+ bool is_linear,
+ SpikePoint const& spike_point)
+ {
+ if (is_linear && AllowSpikes)
+ {
+ return;
+ }
+
+ oss << ". A spike point was found with apex at "
+ << geometry::dsv(spike_point);
+ }
+ };
+
+ template <typename Turns>
+ struct process_data<failure_self_intersections, Turns>
+ {
+ static inline
+ void apply_to_segment_identifier(std::ostringstream& oss,
+ segment_identifier seg_id)
+ {
+ oss << "{" << seg_id.source_index
+ << ", " << seg_id.multi_index
+ << ", " << seg_id.ring_index
+ << ", " << seg_id.segment_index
+ << "}";
+ }
+
+ static inline void apply(std::ostringstream& oss,
+ Turns const& turns)
+ {
+ typedef typename boost::range_value<Turns>::type turn_type;
+ turn_type const& turn = range::front(turns);
+ oss << ". A self-intersection point was found at "
+ << geometry::dsv(turn.point);
+
+ oss << "; method: " << method_char(turn.method)
+ << "; operations: "
+ << operation_char(turn.operations[0].operation)
+ << "/"
+ << operation_char(turn.operations[1].operation)
+ << "; segment IDs {source, multi, ring, segment}: ";
+ apply_to_segment_identifier(oss, turn.operations[0].seg_id);
+ oss << "/";
+ apply_to_segment_identifier(oss, turn.operations[1].seg_id);
+ }
+ };
+
+ template <typename Point>
+ struct process_data<failure_duplicate_points, Point>
+ {
+ static inline void apply(std::ostringstream& oss,
+ Point const& point)
+ {
+ if (AllowDuplicates)
+ {
+ return;
+ }
+ oss << ". Duplicate points were found near point "
+ << geometry::dsv(point);
+ }
+ };
+
+public:
+ failing_reason_policy(std::ostringstream& oss)
+ : m_oss(oss)
+ {}
+
+ template <validity_failure_type Failure>
+ inline bool apply()
+ {
+ validity_failure_type const failure = transform_failure_type(Failure);
+ set_failure_message(failure);
+ return failure == no_failure;
+ }
+
+ template <validity_failure_type Failure, typename Data>
+ inline bool apply(Data const& data)
+ {
+ validity_failure_type const failure = transform_failure_type(Failure);
+ set_failure_message(failure);
+ process_data<Failure, Data>::apply(m_oss, data);
+ return failure == no_failure;
+ }
+
+ template <validity_failure_type Failure, typename Data1, typename Data2>
+ inline bool apply(Data1 const& data1, Data2 const& data2)
+ {
+ validity_failure_type const failure
+ = transform_failure_type(Failure, data1);
+ set_failure_message(failure);
+ process_data<Failure, Data1, Data2>::apply(m_oss, data1, data2);
+ return failure == no_failure;
+ }
+
+private:
+ std::ostringstream& m_oss;
+};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_POLICIES_IS_VALID_FAILING_REASON_POLICY_HPP
diff --git a/3party/boost/boost/geometry/policies/is_valid/failure_type_policy.hpp b/3party/boost/boost/geometry/policies/is_valid/failure_type_policy.hpp
new file mode 100644
index 0000000000..9fb569e283
--- /dev/null
+++ b/3party/boost/boost/geometry/policies/is_valid/failure_type_policy.hpp
@@ -0,0 +1,83 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_POLICIES_IS_VALID_FAILURE_TYPE_POLICY_HPP
+#define BOOST_GEOMETRY_POLICIES_IS_VALID_FAILURE_TYPE_POLICY_HPP
+
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+// policy that simply keeps (and can return) the failure type
+template <bool AllowDuplicates = true, bool AllowSpikes = true>
+class failure_type_policy
+{
+private:
+ static inline
+ validity_failure_type transform_failure_type(validity_failure_type failure)
+ {
+ if (AllowDuplicates && failure == failure_duplicate_points)
+ {
+ return no_failure;
+ }
+ return failure;
+ }
+
+ static inline
+ validity_failure_type transform_failure_type(validity_failure_type failure,
+ bool is_linear)
+ {
+ if (is_linear && AllowSpikes && failure == failure_spikes)
+ {
+ return no_failure;
+ }
+ return transform_failure_type(failure);
+ }
+
+public:
+ failure_type_policy()
+ : m_failure(no_failure)
+ {}
+
+ template <validity_failure_type Failure>
+ inline bool apply()
+ {
+ m_failure = transform_failure_type(Failure);
+ return m_failure == no_failure;
+ }
+
+ template <validity_failure_type Failure, typename Data>
+ inline bool apply(Data const&)
+ {
+ return apply<Failure>();
+ }
+
+ template <validity_failure_type Failure, typename Data1, typename Data2>
+ inline bool apply(Data1 const& data1, Data2 const&)
+ {
+ m_failure = transform_failure_type(Failure, data1);
+ return m_failure == no_failure;
+ }
+
+ validity_failure_type failure() const
+ {
+ return m_failure;
+ }
+
+private:
+ validity_failure_type m_failure;
+};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_POLICIES_IS_VALID_FAILURE_TYPE_POLICY_HPP
diff --git a/3party/boost/boost/geometry/policies/relate/de9im.hpp b/3party/boost/boost/geometry/policies/relate/de9im.hpp
deleted file mode 100644
index e2d6b5111c..0000000000
--- a/3party/boost/boost/geometry/policies/relate/de9im.hpp
+++ /dev/null
@@ -1,168 +0,0 @@
-// 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);
- }
-
-};
-
-
-}} // namespace policies::relate
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
diff --git a/3party/boost/boost/geometry/policies/relate/direction.hpp b/3party/boost/boost/geometry/policies/relate/direction.hpp
index 02fed94b10..2c903bd79f 100644
--- a/3party/boost/boost/geometry/policies/relate/direction.hpp
+++ b/3party/boost/boost/geometry/policies/relate/direction.hpp
@@ -206,22 +206,51 @@ struct segments_direction
}
}
+ static inline int arrival_from_position_value(int /*v_from*/, int v_to)
+ {
+ return v_to == 2 ? 1
+ : v_to == 1 || v_to == 3 ? 0
+ //: v_from >= 1 && v_from <= 3 ? -1
+ : -1;
+
+ // NOTE: this should be an equivalent of the above for the other order
+ /* (v_from < 3 && v_to > 3) || (v_from > 3 && v_to < 3) ? 1
+ : v_from == 3 || v_to == 3 ? 0
+ : -1;*/
+ }
+
+ static inline void analyse_position_value(int pos_val,
+ int & in_segment_count,
+ int & on_end_count,
+ int & outside_segment_count)
+ {
+ if ( pos_val == 1 || pos_val == 3 )
+ {
+ on_end_count++;
+ }
+ else if ( pos_val == 2 )
+ {
+ in_segment_count++;
+ }
+ else
+ {
+ outside_segment_count++;
+ }
+ }
+
template <typename Segment1, typename Segment2, typename Ratio>
static inline return_type segments_collinear(
- Segment1 const& , Segment2 const&,
- Ratio const& ra_from_wrt_b, Ratio const& ra_to_wrt_b,
- Ratio const& rb_from_wrt_a, Ratio const& rb_to_wrt_a)
+ Segment1 const& , Segment2 const& , bool opposite,
+ int a1_wrt_b, int a2_wrt_b, int b1_wrt_a, int b2_wrt_a,
+ Ratio const& /*ra_from_wrt_b*/, Ratio const& /*ra_to_wrt_b*/,
+ Ratio const& /*rb_from_wrt_a*/, Ratio const& /*rb_to_wrt_a*/)
{
- // If segments are opposite, the ratio of the FROM w.r.t. the other
- // is larger than the ratio of the TO w.r.t. the other
- bool const opposite = ra_to_wrt_b < ra_from_wrt_b;
-
return_type r('c', opposite);
// IMPORTANT: the order of conditions is different as in intersection_points.hpp
// We assign A in 0 and B in 1
- r.arrival[0] = arrival_value(ra_from_wrt_b, ra_to_wrt_b);
- r.arrival[1] = arrival_value(rb_from_wrt_a, rb_to_wrt_a);
+ r.arrival[0] = arrival_from_position_value(a1_wrt_b, a2_wrt_b);
+ r.arrival[1] = arrival_from_position_value(b1_wrt_a, b2_wrt_a);
// Analyse them
int a_in_segment_count = 0;
@@ -230,13 +259,13 @@ struct segments_direction
int b_in_segment_count = 0;
int b_on_end_count = 0;
int b_outside_segment_count = 0;
- analyze(ra_from_wrt_b,
+ analyse_position_value(a1_wrt_b,
a_in_segment_count, a_on_end_count, a_outside_segment_count);
- analyze(ra_to_wrt_b,
+ analyse_position_value(a2_wrt_b,
a_in_segment_count, a_on_end_count, a_outside_segment_count);
- analyze(rb_from_wrt_a,
+ analyse_position_value(b1_wrt_a,
b_in_segment_count, b_on_end_count, b_outside_segment_count);
- analyze(rb_to_wrt_a,
+ analyse_position_value(b2_wrt_a,
b_in_segment_count, b_on_end_count, b_outside_segment_count);
if (a_on_end_count == 1
diff --git a/3party/boost/boost/geometry/policies/relate/intersection_points.hpp b/3party/boost/boost/geometry/policies/relate/intersection_points.hpp
index aa2f697a2a..f4a811d5c0 100644
--- a/3party/boost/boost/geometry/policies/relate/intersection_points.hpp
+++ b/3party/boost/boost/geometry/policies/relate/intersection_points.hpp
@@ -18,7 +18,9 @@
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/strategies/side_info.hpp>
+#include <boost/geometry/util/promote_integral.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/util/math.hpp>
@@ -59,13 +61,25 @@ struct segments_intersection_points
// Up to now, division was postponed. Here we divide using numerator/
// denominator. In case of integer this results in an integer
// division.
- BOOST_ASSERT(ratio.denominator() != 0);
- set<0>(point, boost::numeric_cast<coordinate_type>(
- get<0, 0>(segment)
- + ratio.numerator() * dx / ratio.denominator()));
- set<1>(point, boost::numeric_cast<coordinate_type>(
- get<0, 1>(segment)
- + ratio.numerator() * dy / ratio.denominator()));
+ BOOST_GEOMETRY_ASSERT(ratio.denominator() != 0);
+
+ typedef typename promote_integral<coordinate_type>::type promoted_type;
+
+ promoted_type const numerator
+ = boost::numeric_cast<promoted_type>(ratio.numerator());
+ promoted_type const denominator
+ = boost::numeric_cast<promoted_type>(ratio.denominator());
+ promoted_type const dx_promoted = boost::numeric_cast<promoted_type>(dx);
+ promoted_type const dy_promoted = boost::numeric_cast<promoted_type>(dy);
+
+ set<0>(point, get<0, 0>(segment) + boost::numeric_cast
+ <
+ coordinate_type
+ >(numerator * dx_promoted / denominator));
+ set<1>(point, get<0, 1>(segment) + boost::numeric_cast
+ <
+ coordinate_type
+ >(numerator * dy_promoted / denominator));
}
@@ -100,19 +114,20 @@ struct segments_intersection_points
template <typename Segment1, typename Segment2, typename Ratio>
static inline return_type segments_collinear(
- Segment1 const& a, Segment2 const& b,
+ Segment1 const& a, Segment2 const& b, bool /*opposite*/,
+ int a1_wrt_b, int a2_wrt_b, int b1_wrt_a, int b2_wrt_a,
Ratio const& ra_from_wrt_b, Ratio const& ra_to_wrt_b,
Ratio const& rb_from_wrt_a, Ratio const& rb_to_wrt_a)
{
return_type result;
- int index = 0, count_a = 0, count_b = 0;
+ unsigned int index = 0, count_a = 0, count_b = 0;
Ratio on_a[2];
// The conditions "index < 2" are necessary for non-robust handling,
// if index would be 2 this indicate an (currently uncatched) error
// IMPORTANT: the order of conditions is different as in direction.hpp
- if (ra_from_wrt_b.on_segment()
+ if (a1_wrt_b >= 1 && a1_wrt_b <= 3 // ra_from_wrt_b.on_segment()
&& index < 2)
{
// a1--------->a2
@@ -126,7 +141,7 @@ struct segments_intersection_points
index++;
count_a++;
}
- if (rb_from_wrt_a.in_segment()
+ if (b1_wrt_a == 2 //rb_from_wrt_a.in_segment()
&& index < 2)
{
// We take the first intersection point of B
@@ -143,7 +158,7 @@ struct segments_intersection_points
count_b++;
}
- if (ra_to_wrt_b.on_segment()
+ if (a2_wrt_b >= 1 && a2_wrt_b <= 3 //ra_to_wrt_b.on_segment()
&& index < 2)
{
// Similarly, second IP (here a2)
@@ -155,7 +170,7 @@ struct segments_intersection_points
index++;
count_a++;
}
- if (rb_to_wrt_a.in_segment()
+ if (b2_wrt_a == 2 // rb_to_wrt_a.in_segment()
&& index < 2)
{
detail::assign_point_from_index<1>(b, result.intersections[index]);
diff --git a/3party/boost/boost/geometry/policies/relate/tupled.hpp b/3party/boost/boost/geometry/policies/relate/tupled.hpp
index 6da9095c4e..4b65432f20 100644
--- a/3party/boost/boost/geometry/policies/relate/tupled.hpp
+++ b/3party/boost/boost/geometry/policies/relate/tupled.hpp
@@ -47,13 +47,22 @@ struct segments_tupled
template <typename Segment1, typename Segment2, typename Ratio>
static inline return_type segments_collinear(
- Segment1 const& segment1, Segment2 const& segment2,
- Ratio const& ra1, Ratio const& ra2, Ratio const& rb1, Ratio const& rb2)
+ Segment1 const& segment1, Segment2 const& segment2,
+ bool opposite,
+ int pa1, int pa2, int pb1, int pb2,
+ Ratio const& ra1, Ratio const& ra2,
+ Ratio const& rb1, Ratio const& rb2)
{
return boost::make_tuple
(
- Policy1::segments_collinear(segment1, segment2, ra1, ra2, rb1, rb2),
- Policy2::segments_collinear(segment1, segment2, ra1, ra2, rb1, rb2)
+ Policy1::segments_collinear(segment1, segment2,
+ opposite,
+ pa1, pa2, pb1, pb2,
+ ra1, ra2, rb1, rb2),
+ Policy2::segments_collinear(segment1, segment2,
+ opposite,
+ pa1, pa2, pb1, pb2,
+ ra1, ra2, rb1, rb2)
);
}
diff --git a/3party/boost/boost/geometry/policies/robustness/get_rescale_policy.hpp b/3party/boost/boost/geometry/policies/robustness/get_rescale_policy.hpp
index ed7c1eb94c..51e9691525 100644
--- a/3party/boost/boost/geometry/policies/robustness/get_rescale_policy.hpp
+++ b/3party/boost/boost/geometry/policies/robustness/get_rescale_policy.hpp
@@ -1,9 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2014 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2014-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2014-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2014-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -18,6 +23,7 @@
#include <boost/type_traits.hpp>
#include <boost/mpl/assert.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
@@ -41,35 +47,52 @@ namespace boost { namespace geometry
namespace detail { namespace get_rescale_policy
{
-template <typename Point, typename RobustPoint, typename Geometry, typename Factor>
-static inline void init_rescale_policy(Geometry const& geometry,
- Point& min_point,
- RobustPoint& min_robust_point,
- Factor& factor)
+template
+<
+ typename Box,
+ typename Point,
+ typename RobustPoint,
+ typename Factor
+>
+inline void scale_box_to_integer_range(Box const& box,
+ Point& min_point,
+ RobustPoint& min_robust_point,
+ Factor& factor)
{
- // Get bounding boxes
- model::box<Point> env = geometry::return_envelope<model::box<Point> >(geometry);
-
- // Scale this to integer-range
+ // Scale box to integer-range
typedef typename promote_floating_point
<
typename geometry::coordinate_type<Point>::type
>::type num_type;
- num_type const diff = boost::numeric_cast<num_type>(detail::get_max_size(env));
+ num_type const diff = boost::numeric_cast<num_type>(detail::get_max_size(box));
num_type const range = 10000000.0; // Define a large range to get precise integer coordinates
num_type const half = 0.5;
- factor = math::equals(diff, num_type()) ? 1
+ factor = math::equals(diff, num_type()) || diff >= range ? 1
: boost::numeric_cast<num_type>(
boost::numeric_cast<boost::long_long_type>(half + range / diff));
+ BOOST_GEOMETRY_ASSERT(factor >= 1);
+
// Assign input/output minimal points
- detail::assign_point_from_index<0>(env, min_point);
+ detail::assign_point_from_index<0>(box, min_point);
num_type const two = 2;
boost::long_long_type const min_coordinate
= boost::numeric_cast<boost::long_long_type>(-range / two);
assign_values(min_robust_point, min_coordinate, min_coordinate);
}
+template <typename Point, typename RobustPoint, typename Geometry, typename Factor>
+static inline void init_rescale_policy(Geometry const& geometry,
+ Point& min_point,
+ RobustPoint& min_robust_point,
+ Factor& factor)
+{
+ // Get bounding boxes
+ model::box<Point> env = geometry::return_envelope<model::box<Point> >(geometry);
+
+ scale_box_to_integer_range(env, min_point, min_robust_point, factor);
+}
+
template <typename Point, typename RobustPoint, typename Geometry1, typename Geometry2, typename Factor>
static inline void init_rescale_policy(Geometry1 const& geometry1,
Geometry2 const& geometry2,
@@ -82,25 +105,7 @@ static inline void init_rescale_policy(Geometry1 const& geometry1,
model::box<Point> env2 = geometry::return_envelope<model::box<Point> >(geometry2);
geometry::expand(env, env2);
- // TODO: merge this with implementation above
- // Scale this to integer-range
- typedef typename promote_floating_point
- <
- typename geometry::coordinate_type<Point>::type
- >::type num_type;
- num_type const diff = boost::numeric_cast<num_type>(detail::get_max_size(env));
- num_type const range = 10000000.0; // Define a large range to get precise integer coordinates
- num_type const half = 0.5;
- factor = math::equals(diff, num_type()) ? 1
- : boost::numeric_cast<num_type>(
- boost::numeric_cast<boost::long_long_type>(half + range / diff));
-
- // Assign input/output minimal points
- detail::assign_point_from_index<0>(env, min_point);
- num_type const two = 2;
- boost::long_long_type const min_coordinate
- = boost::numeric_cast<boost::long_long_type>(-range / two);
- assign_values(min_robust_point, min_coordinate, min_coordinate);
+ scale_box_to_integer_range(env, min_point, min_robust_point, factor);
}
diff --git a/3party/boost/boost/geometry/policies/robustness/segment_ratio.hpp b/3party/boost/boost/geometry/policies/robustness/segment_ratio.hpp
index 41068c0eb4..bf30f0295a 100644
--- a/3party/boost/boost/geometry/policies/robustness/segment_ratio.hpp
+++ b/3party/boost/boost/geometry/policies/robustness/segment_ratio.hpp
@@ -9,10 +9,10 @@
#ifndef BOOST_GEOMETRY_POLICIES_ROBUSTNESS_SEGMENT_RATIO_HPP
#define BOOST_GEOMETRY_POLICIES_ROBUSTNESS_SEGMENT_RATIO_HPP
-#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/rational.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
@@ -47,8 +47,8 @@ struct less<Type, false>
template <typename Ratio>
static inline bool apply(Ratio const& lhs, Ratio const& rhs)
{
- BOOST_ASSERT(lhs.denominator() != 0);
- BOOST_ASSERT(rhs.denominator() != 0);
+ BOOST_GEOMETRY_ASSERT(lhs.denominator() != 0);
+ BOOST_GEOMETRY_ASSERT(rhs.denominator() != 0);
return lhs.numerator() * rhs.denominator()
< rhs.numerator() * lhs.denominator();
}
@@ -78,8 +78,8 @@ struct equal<Type, false>
template <typename Ratio>
static inline bool apply(Ratio const& lhs, Ratio const& rhs)
{
- BOOST_ASSERT(lhs.denominator() != 0);
- BOOST_ASSERT(rhs.denominator() != 0);
+ BOOST_GEOMETRY_ASSERT(lhs.denominator() != 0);
+ BOOST_GEOMETRY_ASSERT(rhs.denominator() != 0);
return geometry::math::equals
(
lhs.numerator() * rhs.denominator(),
@@ -211,7 +211,10 @@ public :
#if defined(BOOST_GEOMETRY_DEFINE_STREAM_OPERATOR_SEGMENT_RATIO)
friend std::ostream& operator<<(std::ostream &os, segment_ratio const& ratio)
{
- os << ratio.m_numerator << "/" << ratio.m_denominator;
+ os << ratio.m_numerator << "/" << ratio.m_denominator
+ << " (" << (static_cast<double>(ratio.m_numerator)
+ / static_cast<double>(ratio.m_denominator))
+ << ")";
return os;
}
#endif
diff --git a/3party/boost/boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp b/3party/boost/boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp
index c03a1a1d82..446d2f02cd 100644
--- a/3party/boost/boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp
+++ b/3party/boost/boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp
@@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_BUFFER_DISTANCE_ASYMMETRIC_HPP
#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_BUFFER_DISTANCE_ASYMMETRIC_HPP
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/util/math.hpp>
@@ -62,10 +64,10 @@ public :
return negative() ? math::abs(result) : result;
}
- //! Returns 1 (used internally)
+ //! Used internally, returns -1 for deflate, 1 for inflate
inline int factor() const
{
- return m_left < 0 ? -1 : 1;
+ return negative() ? -1 : 1;
}
//! Returns true if both distances are negative
@@ -79,6 +81,8 @@ public :
inline NumericType max_distance(JoinStrategy const& join_strategy,
EndStrategy const& end_strategy) const
{
+ boost::ignore_unused(join_strategy, end_strategy);
+
NumericType const left = geometry::math::abs(m_left);
NumericType const right = geometry::math::abs(m_right);
NumericType const dist = (std::max)(left, right);
diff --git a/3party/boost/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp b/3party/boost/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp
index a8815173bc..73bd21ac73 100644
--- a/3party/boost/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp
+++ b/3party/boost/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp
@@ -9,6 +9,9 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_BUFFER_DISTANCE_SYMMETRIC_HPP
#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_BUFFER_DISTANCE_SYMMETRIC_HPP
+
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/util/math.hpp>
@@ -56,13 +59,13 @@ public :
inline NumericType apply(Point const& , Point const& ,
buffer_side_selector ) const
{
- return m_distance;
+ return negative() ? geometry::math::abs(m_distance) : m_distance;
}
- //! Returns 1 (used internally)
+ //! Used internally, returns -1 for deflate, 1 for inflate
inline int factor() const
{
- return 1;
+ return negative() ? -1 : 1;
}
//! Returns true if distance is negative
@@ -76,6 +79,8 @@ public :
inline NumericType max_distance(JoinStrategy const& join_strategy,
EndStrategy const& end_strategy) const
{
+ boost::ignore_unused(join_strategy, end_strategy);
+
NumericType const dist = geometry::math::abs(m_distance);
return (std::max)(join_strategy.max_distance(dist),
end_strategy.max_distance(dist));
diff --git a/3party/boost/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp b/3party/boost/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
index ce3142d892..0cd0cdc4db 100644
--- a/3party/boost/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
+++ b/3party/boost/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -19,6 +24,7 @@
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/convex_hull.hpp>
@@ -282,17 +288,17 @@ public:
template <typename OutputIterator>
inline void result(partitions const& state,
- OutputIterator out, bool clockwise) const
+ OutputIterator out,
+ bool clockwise,
+ bool closed) const
{
if (clockwise)
{
- output_range<iterate_forward>(state.m_upper_hull, out, false);
- output_range<iterate_reverse>(state.m_lower_hull, out, true);
+ output_ranges(state.m_upper_hull, state.m_lower_hull, out, closed);
}
else
{
- output_range<iterate_forward>(state.m_lower_hull, out, false);
- output_range<iterate_reverse>(state.m_upper_hull, out, true);
+ output_ranges(state.m_lower_hull, state.m_upper_hull, out, closed);
}
}
@@ -343,28 +349,28 @@ private:
}
- template <iterate_direction Direction, typename OutputIterator>
- static inline void output_range(container_type const& range,
- OutputIterator out, bool skip_first)
+ template <typename OutputIterator>
+ static inline void output_ranges(container_type const& first, container_type const& second,
+ OutputIterator out, bool closed)
{
- 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)
+ std::copy(boost::begin(first), boost::end(first), out);
+
+ BOOST_GEOMETRY_ASSERT(closed ? !boost::empty(second) : boost::size(second) > 1);
+ std::copy(++boost::rbegin(second), // skip the first Point
+ closed ? boost::rend(second) : --boost::rend(second), // skip the last Point if open
+ out);
+
+ typedef typename boost::range_size<container_type>::type size_type;
+ size_type const count = boost::size(first) + boost::size(second) - 1;
+ // count describes a closed case but comparison with min size of closed
+ // gives the result compatible also with open
+ // here core_detail::closure::minimum_ring_size<closed> could be used
+ if (count < 4)
{
- if (first && skip_first)
- {
- first = false;
- }
- else
- {
- *out = *it;
- ++out;
- }
+ // there should be only one missing
+ *out++ = *boost::begin(first);
}
}
-
};
}} // namespace strategy::convex_hull
diff --git a/3party/boost/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp b/3party/boost/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp
index e6161b677d..641533fc6a 100644
--- a/3party/boost/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp
+++ b/3party/boost/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp
@@ -19,6 +19,8 @@
#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POLY_WINDING_HPP
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
@@ -71,7 +73,7 @@ struct winding_side_equal
PointOfSegment ss1, ss2;
set<1-D>(ss1, get<1-D>(se));
set<1-D>(ss2, get<1-D>(se));
- if ( count > 0 ) // UP
+ if (count > 0) // UP
{
set<D>(ss1, 0);
set<D>(ss2, 1);
@@ -105,6 +107,81 @@ struct winding_side_equal<cartesian_tag>
};
+template <typename CSTag>
+struct winding_side_between
+{
+ typedef typename strategy::side::services::default_strategy
+ <
+ CSTag
+ >::type strategy_side_type;
+
+ template <size_t D, typename Point, typename PointOfSegment>
+ static inline int apply(Point const& point,
+ PointOfSegment const& s1, PointOfSegment const& s2,
+ int count)
+ {
+ // Create a vertical segment intersecting the original segment's endpoint
+ // equal to the point, with the derived direction (UP/DOWN).
+ // Set only the 2 first coordinates, the other ones are ignored
+ PointOfSegment ss1, ss2;
+ set<1-D>(ss1, get<1-D>(s1));
+ set<1-D>(ss2, get<1-D>(s1));
+
+ if (count > 0) // UP
+ {
+ set<D>(ss1, 0);
+ set<D>(ss2, 1);
+ }
+ else // DOWN
+ {
+ set<D>(ss1, 1);
+ set<D>(ss2, 0);
+ }
+
+ int const seg_side = strategy_side_type::apply(ss1, ss2, s2);
+
+ if (seg_side != 0) // segment not vertical
+ {
+ if (strategy_side_type::apply(ss1, ss2, point) == -seg_side) // point on the opposite side than s2
+ {
+ return -seg_side;
+ }
+ else
+ {
+ set<1-D>(ss1, get<1-D>(s2));
+ set<1-D>(ss2, get<1-D>(s2));
+
+ if (strategy_side_type::apply(ss1, ss2, point) == seg_side) // point behind s2
+ {
+ return seg_side;
+ }
+ }
+ }
+
+ // segment is vertical or point is between p1 and p2
+ return strategy_side_type::apply(s1, s2, point);
+ }
+};
+
+// The specialization for cartesian
+template <>
+struct winding_side_between<cartesian_tag>
+{
+ typedef strategy::side::services::default_strategy
+ <
+ cartesian_tag
+ >::type strategy_side_type;
+
+ template <size_t D, typename Point, typename PointOfSegment>
+ static inline int apply(Point const& point,
+ PointOfSegment const& s1, PointOfSegment const& s2,
+ int /*count*/)
+ {
+ return strategy_side_type::apply(s1, s2, point);
+ }
+};
+
+
/*!
\brief Within detection using winding rule
\ingroup strategies
@@ -221,6 +298,8 @@ public :
PointOfSegment const& s1, PointOfSegment const& s2,
counter& state)
{
+ typedef typename cs_tag<Point>::type cs_t;
+
bool eq1 = false;
bool eq2 = false;
boost::ignore_unused(eq2);
@@ -229,14 +308,15 @@ public :
if (count != 0)
{
int side = 0;
- if ( count == 1 || count == -1 )
+ if (count == 1 || count == -1)
{
- side = winding_side_equal<typename cs_tag<Point>::type>
+ side = winding_side_equal<cs_t>
::template apply<1>(point, eq1 ? s1 : s2, count);
}
- else
+ else // count == 2 || count == -2
{
- side = strategy_side_type::apply(s1, s2, point);
+ side = winding_side_between<cs_t>
+ ::template apply<1>(point, s1, s2, count);
}
if (side == 0)
diff --git a/3party/boost/boost/geometry/strategies/agnostic/relate.hpp b/3party/boost/boost/geometry/strategies/agnostic/relate.hpp
index 318047fadb..676207694f 100644
--- a/3party/boost/boost/geometry/strategies/agnostic/relate.hpp
+++ b/3party/boost/boost/geometry/strategies/agnostic/relate.hpp
@@ -1,17 +1,17 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014 Oracle and/or its affiliates.
+// Copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_RELATE_HPP
#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_RELATE_HPP
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
namespace boost { namespace geometry
@@ -20,13 +20,12 @@ namespace boost { namespace geometry
namespace strategy { namespace relate
{
-template <typename StaticMask>
+template <typename Geometry1, typename Geometry2, typename StaticMask>
struct relate
{
- template <typename Geometry1, typename Geometry2>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
- return detail::relate::relate<StaticMask>(geometry1, geometry2);
+ return geometry::relate(geometry1, geometry2, StaticMask());
}
};
@@ -44,13 +43,29 @@ namespace services
template <typename Geometry1, typename Geometry2, typename AnyTag1, typename AnyTag2, typename AnyCS>
struct default_strategy<AnyTag1, AnyTag2, AnyTag1, AnyTag2, AnyCS, AnyCS, Geometry1, Geometry2>
{
- typedef strategy::relate::relate<detail::relate::static_mask_within> type;
+ typedef strategy::relate::relate
+ <
+ Geometry1,
+ Geometry2,
+ typename detail::de9im::static_mask_within_type
+ <
+ Geometry1, Geometry2
+ >::type
+ > type;
};
template <typename Geometry1, typename Geometry2, typename AnyTag1, typename AnyTag2, typename AnyCS>
struct default_strategy<AnyTag1, AnyTag2, AnyTag1, areal_tag, AnyCS, AnyCS, Geometry1, Geometry2>
{
- typedef strategy::relate::relate<detail::relate::static_mask_within> type;
+ typedef strategy::relate::relate
+ <
+ Geometry1,
+ Geometry2,
+ typename detail::de9im::static_mask_within_type
+ <
+ Geometry1, Geometry2
+ >::type
+ > type;
};
@@ -71,13 +86,29 @@ namespace strategy { namespace covered_by { namespace services
template <typename Geometry1, typename Geometry2, typename AnyTag1, typename AnyTag2, typename AnyCS>
struct default_strategy<AnyTag1, AnyTag2, AnyTag1, AnyTag2, AnyCS, AnyCS, Geometry1, Geometry2>
{
- typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
+ typedef strategy::relate::relate
+ <
+ Geometry1,
+ Geometry2,
+ typename detail::de9im::static_mask_covered_by_type
+ <
+ Geometry1, Geometry2
+ >::type
+ > type;
};
template <typename Geometry1, typename Geometry2, typename AnyTag1, typename AnyTag2, typename AnyCS>
struct default_strategy<AnyTag1, AnyTag2, AnyTag1, areal_tag, AnyCS, AnyCS, Geometry1, Geometry2>
{
- typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
+ typedef strategy::relate::relate
+ <
+ Geometry1,
+ Geometry2,
+ typename detail::de9im::static_mask_covered_by_type
+ <
+ Geometry1, Geometry2
+ >::type
+ > type;
};
diff --git a/3party/boost/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp b/3party/boost/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp
index 8ad3bbc50d..99e7d9b50f 100644
--- a/3party/boost/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp
+++ b/3party/boost/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp
@@ -1,8 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 1995, 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 1995, 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 1995 Maarten Hilferink, Amsterdam, the Netherlands
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,6 +20,9 @@
#include <cstddef>
+#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
+#include <iostream>
+#endif
#include <vector>
#include <boost/range.hpp>
@@ -23,10 +31,7 @@
#include <boost/geometry/strategies/distance.hpp>
-
-//#define GL_DEBUG_DOUGLAS_PEUCKER
-
-#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
#include <boost/geometry/io/dsv/write.hpp>
#endif
@@ -126,7 +131,7 @@ namespace detail
// because we want to consider a candidate point in between
if (size <= 2)
{
-#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
if (begin != end)
{
std::cout << "ignore between " << dsv(begin->p)
@@ -140,7 +145,7 @@ namespace detail
iterator_type last = end - 1;
-#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
std::cout << "find between " << dsv(begin->p)
<< " and " << dsv(last->p)
<< " size=" << size << std::endl;
@@ -155,7 +160,7 @@ namespace detail
{
distance_type dist = ps_distance_strategy.apply(it->p, begin->p, last->p);
-#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
std::cout << "consider " << dsv(it->p)
<< " at " << double(dist)
<< ((dist > max_dist) ? " maybe" : " no")
@@ -173,7 +178,7 @@ namespace detail
// and handle segments in between recursively
if ( less()(max_dist, md) )
{
-#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
std::cout << "use " << dsv(candidate->p) << std::endl;
#endif
@@ -193,6 +198,10 @@ namespace detail
OutputIterator out,
distance_type max_distance) const
{
+#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
+ std::cout << "max distance: " << max_distance
+ << std::endl << std::endl;
+#endif
distance_strategy_type strategy;
// Copy coordinates, a vector of references to all points
@@ -228,8 +237,6 @@ namespace detail
}
};
-
-
}
#endif // DOXYGEN_NO_DETAIL
@@ -269,18 +276,28 @@ public :
PointDistanceStrategy
>::distance_type distance_type;
- typedef distance_type return_type;
-
template <typename Range, typename OutputIterator>
static inline OutputIterator apply(Range const& range,
OutputIterator out,
- distance_type max_distance)
+ distance_type const& max_distance)
{
- return detail::douglas_peucker
+ namespace services = strategy::distance::services;
+
+ typedef typename services::comparable_type
<
- Point,
PointDistanceStrategy
- >().apply(range, out, max_distance);
+ >::type comparable_distance_strategy_type;
+
+ return detail::douglas_peucker
+ <
+ Point, comparable_distance_strategy_type
+ >().apply(range, out,
+ services::result_from_distance
+ <
+ comparable_distance_strategy_type, Point, Point
+ >::apply(comparable_distance_strategy_type(),
+ max_distance)
+ );
}
};
diff --git a/3party/boost/boost/geometry/strategies/buffer.hpp b/3party/boost/boost/geometry/strategies/buffer.hpp
index 7dbe03b4a9..86bdcc37bf 100644
--- a/3party/boost/boost/geometry/strategies/buffer.hpp
+++ b/3party/boost/boost/geometry/strategies/buffer.hpp
@@ -66,7 +66,8 @@ enum piece_type
buffered_round_end,
buffered_flat_end,
buffered_point,
- buffered_concave // always on the inside
+ buffered_concave, // always on the inside
+ piece_type_unknown
};
@@ -82,6 +83,17 @@ enum join_selector
join_spike // collinear, with overlap, next segment goes back
};
+/*!
+\brief Enumerates types of result codes from buffer strategies
+\ingroup enum
+*/
+enum result_code
+{
+ result_normal,
+ result_error_numerical,
+ result_no_output
+};
+
}} // namespace strategy::buffer
diff --git a/3party/boost/boost/geometry/strategies/cartesian/buffer_end_round.hpp b/3party/boost/boost/geometry/strategies/cartesian/buffer_end_round.hpp
index 74780d6165..3d7d5bb467 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/buffer_end_round.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/buffer_end_round.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -62,8 +67,7 @@ private :
DistanceType const& buffer_distance,
RangeOut& range_out) const
{
- PromotedType const two = 2.0;
- PromotedType const two_pi = two * geometry::math::pi<PromotedType>();
+ PromotedType const two_pi = geometry::math::two_pi<PromotedType>();
std::size_t point_buffer_count = m_points_per_circle;
@@ -95,8 +99,9 @@ public :
//! \brief Constructs the strategy
//! \param points_per_circle points which would be used for a full circle
+ //! (if points_per_circle is smaller than 4, it is internally set to 4)
explicit inline end_round(std::size_t points_per_circle = 90)
- : m_points_per_circle(points_per_circle)
+ : m_points_per_circle((points_per_circle < 4u) ? 4u : points_per_circle)
{}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -106,7 +111,7 @@ public :
inline void apply(Point const& penultimate_point,
Point const& perp_left_point,
Point const& ultimate_point,
- Point const& ,
+ Point const& perp_right_point,
buffer_side_selector side,
DistanceStrategy const& distance,
RangeOut& range_out) const
@@ -142,6 +147,13 @@ public :
set<1>(shifted_point, get<1>(ultimate_point) + dist_half_diff * sin(alpha));
generate_points(shifted_point, alpha, (dist_left + dist_right) / two, range_out);
}
+
+ if (m_points_per_circle % 2 == 1)
+ {
+ // For a half circle, if the number of points is not even,
+ // we should insert the end point too, to generate a full cap
+ range_out.push_back(perp_right_point);
+ }
}
template <typename NumericType>
diff --git a/3party/boost/boost/geometry/strategies/cartesian/buffer_join_miter.hpp b/3party/boost/boost/geometry/strategies/cartesian/buffer_join_miter.hpp
index 8fcf3b996c..5358156f6d 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/buffer_join_miter.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/buffer_join_miter.hpp
@@ -9,7 +9,7 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_MITER_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_MITER_HPP
-#include <boost/assert.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/util/math.hpp>
@@ -35,6 +35,8 @@ namespace strategy { namespace buffer
their length. The miter is not changed to a bevel form (as done in some
other software), it is just adapted to the specified miter_limit but keeps
its miter form.
+ If the buffer distance is 5.0, and the miter limit is 2.0, generated points
+ will be located at a distance of at most 10.0 (2*5) units.
This strategy is only applicable for Cartesian coordinate systems.
\qbk{
@@ -97,7 +99,7 @@ public:
if (distance > max_distance)
{
- BOOST_ASSERT(distance != 0.0);
+ BOOST_GEOMETRY_ASSERT(distance != 0.0);
promoted_type const proportion = max_distance / distance;
set<0>(p, get<0>(vertex) + dx * proportion);
diff --git a/3party/boost/boost/geometry/strategies/cartesian/buffer_join_round.hpp b/3party/boost/boost/geometry/strategies/cartesian/buffer_join_round.hpp
index 9e467c85a0..b4baa33710 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/buffer_join_round.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/buffer_join_round.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,7 +14,8 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP
-#include <boost/assert.hpp>
+#include <algorithm>
+
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/strategies/buffer.hpp>
@@ -69,34 +75,37 @@ private :
DistanceType const& buffer_distance,
RangeOut& range_out) const
{
- PromotedType dx1 = get<0>(perp1) - get<0>(vertex);
- PromotedType dy1 = get<1>(perp1) - get<1>(vertex);
- PromotedType dx2 = get<0>(perp2) - get<0>(vertex);
- PromotedType dy2 = get<1>(perp2) - get<1>(vertex);
+ PromotedType const dx1 = get<0>(perp1) - get<0>(vertex);
+ PromotedType const dy1 = get<1>(perp1) - get<1>(vertex);
+ PromotedType const dx2 = get<0>(perp2) - get<0>(vertex);
+ PromotedType const dy2 = get<1>(perp2) - get<1>(vertex);
- BOOST_ASSERT(buffer_distance != 0);
+ PromotedType const two_pi = geometry::math::two_pi<PromotedType>();
- dx1 /= buffer_distance;
- dy1 /= buffer_distance;
- dx2 /= buffer_distance;
- dy2 /= buffer_distance;
+ PromotedType const angle1 = atan2(dy1, dx1);
+ PromotedType angle2 = atan2(dy2, dx2);
+ while (angle2 > angle1)
+ {
+ angle2 -= two_pi;
+ }
+ PromotedType const angle_diff = angle1 - angle2;
- PromotedType angle_diff = acos(dx1 * dx2 + dy1 * dy2);
+ // Divide the angle into an integer amount of steps to make it
+ // visually correct also for a low number of points / circle
- PromotedType two = 2.0;
- PromotedType steps = m_points_per_circle;
- int n = boost::numeric_cast<int>(steps * angle_diff
- / (two * geometry::math::pi<PromotedType>()));
+ // If a full circle is divided into 3 parts (e.g. angle is 125),
+ // the one point in between must still be generated
+ // The calculation below:
+ // - generates 1 point in between for an angle of 125 based on 3 points
+ // - generates 0 points in between for an angle of 90 based on 4 points
- if (n <= 1)
- {
- return;
- }
+ int const n = (std::max)(static_cast<int>(
+ ceil(m_points_per_circle * angle_diff / two_pi)), 1);
- PromotedType const angle1 = atan2(dy1, dx1);
- PromotedType diff = angle_diff / PromotedType(n);
+ PromotedType const diff = angle_diff / static_cast<PromotedType>(n);
PromotedType a = angle1 - diff;
+ // Walk to n - 1 to avoid generating the last point
for (int i = 0; i < n - 1; i++, a -= diff)
{
Point p;
diff --git a/3party/boost/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp b/3party/boost/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp
index 1444c795af..ed3a010cd5 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/buffer_join_round_by_divide.hpp
@@ -9,7 +9,6 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_BY_DIVIDE_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_BY_DIVIDE_HPP
-#include <boost/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/strategies/buffer.hpp>
diff --git a/3party/boost/boost/geometry/strategies/cartesian/buffer_point_circle.hpp b/3party/boost/boost/geometry/strategies/cartesian/buffer_point_circle.hpp
index f64a82d8fc..f289857177 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/buffer_point_circle.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/buffer_point_circle.hpp
@@ -1,5 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -45,9 +52,10 @@ class point_circle
{
public :
//! \brief Constructs the strategy
- //! \param count number of points for the created circle
+ //! \param count number of points for the created circle (if count
+ //! is smaller than 3, count is internally set to 3)
explicit point_circle(std::size_t count = 90)
- : m_count(count)
+ : m_count((count < 3u) ? 3u : count)
{}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -77,8 +85,7 @@ public :
promoted_type const buffer_distance = distance_strategy.apply(point, point,
strategy::buffer::buffer_side_left);
- promoted_type const two = 2.0;
- promoted_type const two_pi = two * geometry::math::pi<promoted_type>();
+ promoted_type const two_pi = geometry::math::two_pi<promoted_type>();
promoted_type const diff = two_pi / promoted_type(m_count);
promoted_type a = 0;
diff --git a/3party/boost/boost/geometry/strategies/cartesian/buffer_side_straight.hpp b/3party/boost/boost/geometry/strategies/cartesian/buffer_side_straight.hpp
index b5d28e2577..75247377fa 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/buffer_side_straight.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/buffer_side_straight.hpp
@@ -9,7 +9,7 @@
#include <cstddef>
-#include <boost/assert.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/access.hpp>
@@ -53,9 +53,9 @@ public :
typename OutputRange,
typename DistanceStrategy
>
- static inline void apply(
+ static inline result_code apply(
Point const& input_p1, Point const& input_p2,
- strategy::buffer::buffer_side_selector side,
+ buffer_side_selector side,
DistanceStrategy const& distance,
OutputRange& output_range)
{
@@ -69,20 +69,52 @@ public :
// Generate a block along (left or right of) the segment
// Simulate a vector d (dx,dy)
- coordinate_type dx = get<0>(input_p2) - get<0>(input_p1);
- coordinate_type dy = get<1>(input_p2) - get<1>(input_p1);
+ coordinate_type const dx = get<0>(input_p2) - get<0>(input_p1);
+ coordinate_type const dy = get<1>(input_p2) - get<1>(input_p1);
// For normalization [0,1] (=dot product d.d, sqrt)
promoted_type const length = geometry::math::sqrt(dx * dx + dy * dy);
- // Because coordinates are not equal, length should not be zero
- BOOST_ASSERT((! geometry::math::equals(length, 0)));
+ if (! boost::math::isfinite(length))
+ {
+ // In case of coordinates differences of e.g. 1e300, length
+ // will overflow and we should not generate output
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
+ std::cout << "Error in length calculation for points "
+ << geometry::wkt(input_p1) << " " << geometry::wkt(input_p2)
+ << " length: " << length << std::endl;
+#endif
+ return result_error_numerical;
+ }
+
+ if (geometry::math::equals(length, 0))
+ {
+ // Coordinates are simplified and therefore most often not equal.
+ // But if simplify is skipped, or for lines with two
+ // equal points, length is 0 and we cannot generate output.
+ return result_no_output;
+ }
+
+ promoted_type const d = distance.apply(input_p1, input_p2, side);
// Generate the normalized perpendicular p, to the left (ccw)
promoted_type const px = -dy / length;
promoted_type const py = dx / length;
- promoted_type const d = distance.apply(input_p1, input_p2, side);
+ if (geometry::math::equals(px, 0)
+ && geometry::math::equals(py, 0))
+ {
+ // This basically should not occur - because of the checks above.
+ // There are no unit tests triggering this condition
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
+ std::cout << "Error in perpendicular calculation for points "
+ << geometry::wkt(input_p1) << " " << geometry::wkt(input_p2)
+ << " length: " << length
+ << " distance: " << d
+ << std::endl;
+#endif
+ return result_no_output;
+ }
output_range.resize(2);
@@ -90,6 +122,8 @@ public :
set<1>(output_range.front(), get<1>(input_p1) + py * d);
set<0>(output_range.back(), get<0>(input_p2) + px * d);
set<1>(output_range.back(), get<1>(input_p2) + py * d);
+
+ return result_normal;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
};
diff --git a/3party/boost/boost/geometry/strategies/cartesian/cart_intersect.hpp b/3party/boost/boost/geometry/strategies/cartesian/cart_intersect.hpp
index 66af2d2e9c..4b3010a405 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/cart_intersect.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/cart_intersect.hpp
@@ -1,7 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -194,7 +200,11 @@ struct relate_cartesian_segments
get<1>(robust_b1) - get<1>(robust_a1),
robust_db0, robust_db);
- if (robust_da0 == 0)
+ math::detail::equals_factor_policy<robust_coordinate_type>
+ policy(robust_dx_a, robust_dy_a, robust_dx_b, robust_dy_b);
+ robust_coordinate_type const zero = 0;
+ if (math::detail::equals_by_policy(robust_da0, zero, policy)
+ || math::detail::equals_by_policy(robust_db0, zero, policy))
{
// If this is the case, no rescaling is done for FP precision.
// We set it to collinear, but it indicates a robustness issue.
@@ -211,25 +221,31 @@ struct relate_cartesian_segments
if (collinear)
{
- bool const collinear_use_first
- = geometry::math::abs(robust_dx_a) + geometry::math::abs(robust_dx_b)
- >= geometry::math::abs(robust_dy_a) + geometry::math::abs(robust_dy_b);
-
- // Degenerate cases: segments of single point, lying on other segment, are not disjoint
- // This situation is collinear too
-
- if (collinear_use_first)
+ std::pair<bool, bool> const collinear_use_first
+ = is_x_more_significant(geometry::math::abs(robust_dx_a),
+ geometry::math::abs(robust_dy_a),
+ geometry::math::abs(robust_dx_b),
+ geometry::math::abs(robust_dy_b),
+ a_is_point, b_is_point);
+
+ if (collinear_use_first.second)
{
- return relate_collinear<0, ratio_type>(a, b,
- robust_a1, robust_a2, robust_b1, robust_b2,
- a_is_point, b_is_point);
- }
- else
- {
- // Y direction contains larger segments (maybe dx is zero)
- return relate_collinear<1, ratio_type>(a, b,
- robust_a1, robust_a2, robust_b1, robust_b2,
- a_is_point, b_is_point);
+ // Degenerate cases: segments of single point, lying on other segment, are not disjoint
+ // This situation is collinear too
+
+ if (collinear_use_first.first)
+ {
+ return relate_collinear<0, ratio_type>(a, b,
+ robust_a1, robust_a2, robust_b1, robust_b2,
+ a_is_point, b_is_point);
+ }
+ else
+ {
+ // Y direction contains larger segments (maybe dx is zero)
+ return relate_collinear<1, ratio_type>(a, b,
+ robust_a1, robust_a2, robust_b1, robust_b2,
+ a_is_point, b_is_point);
+ }
}
}
@@ -237,6 +253,40 @@ struct relate_cartesian_segments
}
private:
+ // first is true if x is more significant
+ // second is true if the more significant difference is not 0
+ template <typename RobustCoordinateType>
+ static inline std::pair<bool, bool>
+ is_x_more_significant(RobustCoordinateType const& abs_robust_dx_a,
+ RobustCoordinateType const& abs_robust_dy_a,
+ RobustCoordinateType const& abs_robust_dx_b,
+ RobustCoordinateType const& abs_robust_dy_b,
+ bool const a_is_point,
+ bool const b_is_point)
+ {
+ //BOOST_GEOMETRY_ASSERT_MSG(!(a_is_point && b_is_point), "both segments shouldn't be degenerated");
+
+ // for degenerated segments the second is always true because this function
+ // shouldn't be called if both segments were degenerated
+
+ if (a_is_point)
+ {
+ return std::make_pair(abs_robust_dx_b >= abs_robust_dy_b, true);
+ }
+ else if (b_is_point)
+ {
+ return std::make_pair(abs_robust_dx_a >= abs_robust_dy_a, true);
+ }
+ else
+ {
+ RobustCoordinateType const min_dx = (std::min)(abs_robust_dx_a, abs_robust_dx_b);
+ RobustCoordinateType const min_dy = (std::min)(abs_robust_dy_a, abs_robust_dy_b);
+ return min_dx == min_dy ?
+ std::make_pair(true, min_dx > RobustCoordinateType(0)) :
+ std::make_pair(min_dx > min_dy, true);
+ }
+ }
+
template
<
std::size_t Dimension,
@@ -319,17 +369,58 @@ private:
RobustType const length_a = oa_2 - oa_1; // no abs, see above
RobustType const length_b = ob_2 - ob_1;
- RatioType const ra_from(oa_1 - ob_1, length_b);
- RatioType const ra_to(oa_2 - ob_1, length_b);
- RatioType const rb_from(ob_1 - oa_1, length_a);
- RatioType const rb_to(ob_2 - oa_1, length_a);
+ RatioType ra_from(oa_1 - ob_1, length_b);
+ RatioType ra_to(oa_2 - ob_1, length_b);
+ RatioType rb_from(ob_1 - oa_1, length_a);
+ RatioType rb_to(ob_2 - oa_1, length_a);
+
+ // use absolute measure to detect endpoints intersection
+ // NOTE: it'd be possible to calculate bx_wrt_a using ax_wrt_b values
+ int const a1_wrt_b = position_value(oa_1, ob_1, ob_2);
+ int const a2_wrt_b = position_value(oa_2, ob_1, ob_2);
+ int const b1_wrt_a = position_value(ob_1, oa_1, oa_2);
+ int const b2_wrt_a = position_value(ob_2, oa_1, oa_2);
+
+ // fix the ratios if necessary
+ // CONSIDER: fixing ratios also in other cases, if they're inconsistent
+ // e.g. if ratio == 1 or 0 (so IP at the endpoint)
+ // but position value indicates that the IP is in the middle of the segment
+ // because one of the segments is very long
+ // In such case the ratios could be moved into the middle direction
+ // by some small value (e.g. EPS+1ULP)
+ if (a1_wrt_b == 1)
+ {
+ ra_from.assign(0, 1);
+ rb_from.assign(0, 1);
+ }
+ else if (a1_wrt_b == 3)
+ {
+ ra_from.assign(1, 1);
+ rb_to.assign(0, 1);
+ }
+
+ if (a2_wrt_b == 1)
+ {
+ ra_to.assign(0, 1);
+ rb_from.assign(1, 1);
+ }
+ else if (a2_wrt_b == 3)
+ {
+ ra_to.assign(1, 1);
+ rb_to.assign(1, 1);
+ }
- if ((ra_from.left() && ra_to.left()) || (ra_from.right() && ra_to.right()))
+ if ((a1_wrt_b < 1 && a2_wrt_b < 1) || (a1_wrt_b > 3 && a2_wrt_b > 3))
+ //if ((ra_from.left() && ra_to.left()) || (ra_from.right() && ra_to.right()))
{
return Policy::disjoint();
}
- return Policy::segments_collinear(a, b, ra_from, ra_to, rb_from, rb_to);
+ bool const opposite = math::sign(length_a) != math::sign(length_b);
+
+ return Policy::segments_collinear(a, b, opposite,
+ a1_wrt_b, a2_wrt_b, b1_wrt_a, b2_wrt_a,
+ ra_from, ra_to, rb_from, rb_to);
}
/// Relate segments where one is degenerate
@@ -351,8 +442,32 @@ private:
// b1/b2 (4..4)
// Ratio: (4-2)/(6-2)
RatioType const ratio(d - s1, s2 - s1);
+
+ if (!ratio.on_segment())
+ {
+ return Policy::disjoint();
+ }
+
return Policy::one_degenerate(degenerate_segment, ratio, a_degenerate);
}
+
+ template <typename ProjCoord1, typename ProjCoord2>
+ static inline int position_value(ProjCoord1 const& ca1,
+ ProjCoord2 const& cb1,
+ ProjCoord2 const& cb2)
+ {
+ // S1x 0 1 2 3 4
+ // S2 |---------->
+ return math::equals(ca1, cb1) ? 1
+ : math::equals(ca1, cb2) ? 3
+ : cb1 < cb2 ?
+ ( ca1 < cb1 ? 0
+ : ca1 > cb2 ? 4
+ : 2 )
+ : ( ca1 > cb1 ? 0
+ : ca1 < cb2 ? 4
+ : 2 );
+ }
};
diff --git a/3party/boost/boost/geometry/strategies/cartesian/centroid_average.hpp b/3party/boost/boost/geometry/strategies/cartesian/centroid_average.hpp
index 76e2f7144c..c12f6e2024 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/centroid_average.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/centroid_average.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,6 +20,8 @@
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP
+#include <cstddef>
+
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
@@ -46,7 +53,7 @@ private :
class sum
{
friend class average;
- int count;
+ std::size_t count;
PointCentroid centroid;
public :
@@ -68,10 +75,15 @@ public :
state.count++;
}
- static inline void result(sum const& state, PointCentroid& centroid)
+ static inline bool result(sum const& state, PointCentroid& centroid)
{
centroid = state.centroid;
- divide_value(centroid, state.count);
+ if ( state.count > 0 )
+ {
+ divide_value(centroid, state.count);
+ return true;
+ }
+ return false;
}
};
diff --git a/3party/boost/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp b/3party/boost/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
index f199fb80e5..47763a9f30 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,6 +20,9 @@
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
+#include <cstddef>
+
+#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits.hpp>
@@ -143,7 +151,7 @@ private :
class sums
{
friend class bashein_detmer;
- int count;
+ std::size_t count;
calculation_type sum_a2;
calculation_type sum_x;
calculation_type sum_y;
@@ -199,11 +207,18 @@ public :
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;
+ // Prevent NaN centroid coordinates
+ if (boost::math::isfinite(a3))
+ {
+ // NOTE: above calculation_type is checked, not the centroid coordinate_type
+ // which means that the centroid can still be filled with INF
+ // if e.g. calculation_type is double and centroid contains floats
+ 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;
diff --git a/3party/boost/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp b/3party/boost/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
index b788738d15..0735e925b6 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
@@ -1,7 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2009-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -13,9 +18,13 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
#include <boost/geometry/algorithms/detail/distance/interface.hpp>
#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/util/for_each_coordinate.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/strategies/centroid.hpp>
#include <boost/geometry/strategies/default_distance_result.hpp>
@@ -91,17 +100,37 @@ public :
static inline bool result(state_type const& state, Point& centroid)
{
distance_type const zero = distance_type();
- if (! geometry::math::equals(state.length, zero))
+ if (! geometry::math::equals(state.length, zero)
+ && boost::math::isfinite(state.length)) // Prevent NaN centroid coordinates
{
- assign_zero(centroid);
- add_point(centroid, state.average_sum);
- divide_value(centroid, state.length);
+ // NOTE: above distance_type is checked, not the centroid coordinate_type
+ // which means that the centroid can still be filled with INF
+ // if e.g. distance_type is double and centroid contains floats
+ geometry::for_each_coordinate(centroid, set_sum_div_length(state));
return true;
}
return false;
}
+ struct set_sum_div_length
+ {
+ state_type const& m_state;
+ set_sum_div_length(state_type const& state)
+ : m_state(state)
+ {}
+ template <typename Pt, std::size_t Dimension>
+ void apply(Pt & centroid) const
+ {
+ typedef typename geometry::coordinate_type<Pt>::type coordinate_type;
+ geometry::set<Dimension>(
+ centroid,
+ boost::numeric_cast<coordinate_type>(
+ geometry::get<Dimension>(m_state.average_sum) / m_state.length
+ )
+ );
+ }
+ };
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
diff --git a/3party/boost/boost/geometry/strategies/cartesian/distance_comparable_to_regular.hpp b/3party/boost/boost/geometry/strategies/cartesian/distance_comparable_to_regular.hpp
deleted file mode 100644
index cf432ee82a..0000000000
--- a/3party/boost/boost/geometry/strategies/cartesian/distance_comparable_to_regular.hpp
+++ /dev/null
@@ -1,107 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2014, Oracle and/or its affiliates.
-
-// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
-
-// Licensed under the Boost Software License version 1.0.
-// http://www.boost.org/users/license.html
-
-#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_COMPARABLE_TO_REGULAR_HPP
-#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_COMPARABLE_TO_REGULAR_HPP
-
-
-#include <cmath>
-#include <boost/geometry/strategies/distance_comparable_to_regular.hpp>
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/util/math.hpp>
-
-namespace boost { namespace geometry
-{
-
-namespace strategy { namespace distance
-{
-
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-namespace services
-{
-
-
-template
-<
- typename ComparableStrategy,
- typename Strategy,
- typename Geometry1,
- typename Geometry2
->
-struct comparable_to_regular
- <
- ComparableStrategy, Strategy,
- Geometry1, Geometry2,
- cartesian_tag, cartesian_tag
- >
-{
- typedef typename return_type
- <
- Strategy,
- typename point_type<Geometry1>::type,
- typename point_type<Geometry2>::type
- >::type calculation_type;
-
- typedef typename return_type
- <
- ComparableStrategy,
- typename point_type<Geometry1>::type,
- typename point_type<Geometry2>::type
- >::type comparable_calculation_type;
-
- static inline calculation_type apply(comparable_calculation_type const& cd)
- {
- return math::sqrt( boost::numeric_cast<calculation_type>(cd) );
- }
-};
-
-
-
-template <typename ComparableStrategy, typename Geometry1, typename Geometry2>
-struct comparable_to_regular
- <
- ComparableStrategy,
- ComparableStrategy,
- Geometry1,
- Geometry2,
- cartesian_tag,
- cartesian_tag
- >
-{
- typedef typename return_type
- <
- ComparableStrategy,
- typename point_type<Geometry1>::type,
- typename point_type<Geometry2>::type
- >::type comparable_calculation_type;
-
- static inline comparable_calculation_type
- apply(comparable_calculation_type const& cd)
- {
- return cd;
- }
-};
-
-
-
-
-
-
-
-} // namespace services
-#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-
-
-}} // namespace strategy::distance
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_COMPARABLE_TO_REGULAR_HPP
diff --git a/3party/boost/boost/geometry/strategies/cartesian/side_by_triangle.hpp b/3party/boost/boost/geometry/strategies/cartesian/side_by_triangle.hpp
index 5d589ffc86..77443d46a9 100644
--- a/3party/boost/boost/geometry/strategies/cartesian/side_by_triangle.hpp
+++ b/3party/boost/boost/geometry/strategies/cartesian/side_by_triangle.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -22,6 +27,9 @@
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/algorithms/detail/relate/less.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+
namespace boost { namespace geometry
{
@@ -38,6 +46,24 @@ namespace strategy { namespace side
template <typename CalculationType = void>
class side_by_triangle
{
+ template <typename Policy>
+ struct eps_policy
+ {
+ eps_policy() {}
+ template <typename Type>
+ eps_policy(Type const& a, Type const& b, Type const& c, Type const& d)
+ : policy(a, b, c, d)
+ {}
+ Policy policy;
+ };
+
+ struct eps_empty
+ {
+ eps_empty() {}
+ template <typename Type>
+ eps_empty(Type const&, Type const&, Type const&, Type const&) {}
+ };
+
public :
// Template member function, because it is not always trivial
@@ -47,23 +73,34 @@ public :
// Types can be all three different. Therefore it is
// not implemented (anymore) as "segment"
- template <typename coordinate_type, typename promoted_type, typename P1, typename P2, typename P>
- static inline promoted_type side_value(P1 const& p1, P2 const& p2, P const& p)
+ template
+ <
+ typename CoordinateType,
+ typename PromotedType,
+ typename P1,
+ typename P2,
+ typename P,
+ typename EpsPolicy
+ >
+ static inline
+ PromotedType side_value(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & eps_policy)
{
- coordinate_type const x = get<0>(p);
- coordinate_type const y = get<1>(p);
+ CoordinateType const x = get<0>(p);
+ CoordinateType 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);
+ CoordinateType const sx1 = get<0>(p1);
+ CoordinateType const sy1 = get<1>(p1);
+ CoordinateType const sx2 = get<0>(p2);
+ CoordinateType const sy2 = get<1>(p2);
- promoted_type const dx = sx2 - sx1;
- promoted_type const dy = sy2 - sy1;
- promoted_type const dpx = x - sx1;
- promoted_type const dpy = y - sy1;
+ PromotedType const dx = sx2 - sx1;
+ PromotedType const dy = sy2 - sy1;
+ PromotedType const dpx = x - sx1;
+ PromotedType const dpy = y - sy1;
- return geometry::detail::determinant<promoted_type>
+ eps_policy = EpsPolicy(dx, dy, dpx, dpy);
+
+ return geometry::detail::determinant<PromotedType>
(
dx, dy,
dpx, dpy
@@ -71,9 +108,99 @@ public :
}
+ template
+ <
+ typename CoordinateType,
+ typename PromotedType,
+ typename P1,
+ typename P2,
+ typename P
+ >
+ static inline
+ PromotedType side_value(P1 const& p1, P2 const& p2, P const& p)
+ {
+ eps_empty dummy;
+ return side_value<CoordinateType, PromotedType>(p1, p2, p, dummy);
+ }
+
+
+ template
+ <
+ typename CoordinateType,
+ typename PromotedType,
+ bool AreAllIntegralCoordinates
+ >
+ struct compute_side_value
+ {
+ template <typename P1, typename P2, typename P, typename EpsPolicy>
+ static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
+ {
+ return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
+ }
+ };
+
+ template <typename CoordinateType, typename PromotedType>
+ struct compute_side_value<CoordinateType, PromotedType, false>
+ {
+ template <typename P1, typename P2, typename P, typename EpsPolicy>
+ static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
+ {
+ // For robustness purposes, first check if any two points are
+ // the same; in this case simply return that the points are
+ // collinear
+ if (geometry::detail::equals::equals_point_point(p1, p2)
+ || geometry::detail::equals::equals_point_point(p1, p)
+ || geometry::detail::equals::equals_point_point(p2, p))
+ {
+ return PromotedType(0);
+ }
+
+ // The side_by_triangle strategy computes the signed area of
+ // the point triplet (p1, p2, p); as such it is (in theory)
+ // invariant under cyclic permutations of its three arguments.
+ //
+ // In the context of numerical errors that arise in
+ // floating-point computations, and in order to make the strategy
+ // consistent with respect to cyclic permutations of its three
+ // arguments, we cyclically permute them so that the first
+ // argument is always the lexicographically smallest point.
+
+ geometry::detail::relate::less less;
+ if (less(p, p1))
+ {
+ if (less(p, p2))
+ {
+ // p is the lexicographically smallest
+ return side_value<CoordinateType, PromotedType>(p, p1, p2, epsp);
+ }
+ else
+ {
+ // p2 is the lexicographically smallest
+ return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
+ }
+ }
+
+ if (less(p1, p2))
+ {
+ // p1 is the lexicographically smallest
+ return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
+ }
+ else
+ {
+ // p2 is the lexicographically smallest
+ return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
+ }
+ }
+ };
+
+
template <typename P1, typename P2, typename P>
static inline int apply(P1 const& p1, P2 const& p2, P const& p)
{
+ typedef typename coordinate_type<P1>::type coordinate_type1;
+ typedef typename coordinate_type<P2>::type coordinate_type2;
+ typedef typename coordinate_type<P>::type coordinate_type3;
+
typedef typename boost::mpl::if_c
<
boost::is_void<CalculationType>::type::value,
@@ -81,10 +208,9 @@ public :
<
typename select_most_precise
<
- typename coordinate_type<P1>::type,
- typename coordinate_type<P2>::type
+ coordinate_type1, coordinate_type2
>::type,
- typename coordinate_type<P>::type
+ coordinate_type3
>::type,
CalculationType
>::type coordinate_type;
@@ -96,10 +222,19 @@ public :
double
>::type promoted_type;
- promoted_type const s = side_value<coordinate_type, promoted_type>(p1, p2, p);
- promoted_type const zero = promoted_type();
+ bool const are_all_integral_coordinates =
+ boost::is_integral<coordinate_type1>::value
+ && boost::is_integral<coordinate_type2>::value
+ && boost::is_integral<coordinate_type3>::value;
- return math::equals(s, zero) ? 0
+ eps_policy< math::detail::equals_factor_policy<promoted_type> > epsp;
+ promoted_type s = compute_side_value
+ <
+ coordinate_type, promoted_type, are_all_integral_coordinates
+ >::apply(p1, p2, p, epsp);
+
+ promoted_type const zero = promoted_type();
+ return math::detail::equals_by_policy(s, zero, epsp.policy) ? 0
: s > zero ? 1
: -1;
}
diff --git a/3party/boost/boost/geometry/strategies/cartesian/side_of_intersection.hpp b/3party/boost/boost/geometry/strategies/cartesian/side_of_intersection.hpp
new file mode 100644
index 0000000000..db57644ad5
--- /dev/null
+++ b/3party/boost/boost/geometry/strategies/cartesian/side_of_intersection.hpp
@@ -0,0 +1,349 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_OF_INTERSECTION_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_OF_INTERSECTION_HPP
+
+
+#include <limits>
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+
+#include <boost/geometry/arithmetic/determinant.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
+#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
+#include <boost/math/common_factor_ct.hpp>
+#include <boost/math/common_factor_rt.hpp>
+#include <boost/multiprecision/cpp_int.hpp>
+#endif
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace side
+{
+
+namespace detail
+{
+
+// A tool for multiplication of integers avoiding overflow
+// It's a temporary workaround until we can use Multiprecision
+// The algorithm is based on Karatsuba algorithm
+// see: http://en.wikipedia.org/wiki/Karatsuba_algorithm
+template <typename T>
+struct multiplicable_integral
+{
+ // Currently this tool can't be used with non-integral coordinate types.
+ // Also side_of_intersection strategy sign_of_product() and sign_of_compare()
+ // functions would have to be modified to properly support floating-point
+ // types (comparisons and multiplication).
+ BOOST_STATIC_ASSERT(boost::is_integral<T>::value);
+
+ static const std::size_t bits = CHAR_BIT * sizeof(T);
+ static const std::size_t half_bits = bits / 2;
+ typedef typename boost::make_unsigned<T>::type unsigned_type;
+ static const unsigned_type base = unsigned_type(1) << half_bits; // 2^half_bits
+
+ int m_sign;
+ unsigned_type m_ms;
+ unsigned_type m_ls;
+
+ multiplicable_integral(int sign, unsigned_type ms, unsigned_type ls)
+ : m_sign(sign), m_ms(ms), m_ls(ls)
+ {}
+
+ explicit multiplicable_integral(T const& val)
+ {
+ unsigned_type val_u = val > 0 ?
+ unsigned_type(val)
+ : val == (std::numeric_limits<T>::min)() ?
+ unsigned_type((std::numeric_limits<T>::max)()) + 1
+ : unsigned_type(-val);
+ // MMLL -> S 00MM 00LL
+ m_sign = math::sign(val);
+ m_ms = val_u >> half_bits; // val_u / base
+ m_ls = val_u - m_ms * base;
+ }
+
+ friend multiplicable_integral operator*(multiplicable_integral const& a,
+ multiplicable_integral const& b)
+ {
+ // (S 00MM 00LL) * (S 00MM 00LL) -> (S Z2MM 00LL)
+ unsigned_type z2 = a.m_ms * b.m_ms;
+ unsigned_type z0 = a.m_ls * b.m_ls;
+ unsigned_type z1 = (a.m_ms + a.m_ls) * (b.m_ms + b.m_ls) - z2 - z0;
+ // z0 may be >= base so it must be normalized to allow comparison
+ unsigned_type z0_ms = z0 >> half_bits; // z0 / base
+ return multiplicable_integral(a.m_sign * b.m_sign,
+ z2 * base + z1 + z0_ms,
+ z0 - base * z0_ms);
+ }
+
+ friend bool operator<(multiplicable_integral const& a,
+ multiplicable_integral const& b)
+ {
+ if ( a.m_sign == b.m_sign )
+ {
+ bool u_less = a.m_ms < b.m_ms
+ || (a.m_ms == b.m_ms && a.m_ls < b.m_ls);
+ return a.m_sign > 0 ? u_less : (! u_less);
+ }
+ else
+ {
+ return a.m_sign < b.m_sign;
+ }
+ }
+
+ friend bool operator>(multiplicable_integral const& a,
+ multiplicable_integral const& b)
+ {
+ return b < a;
+ }
+
+ template <typename CmpVal>
+ void check_value(CmpVal const& cmp_val) const
+ {
+ unsigned_type b = base; // a workaround for MinGW - undefined reference base
+ CmpVal val = CmpVal(m_sign) * (CmpVal(m_ms) * CmpVal(b) + CmpVal(m_ls));
+ BOOST_GEOMETRY_ASSERT(cmp_val == val);
+ }
+};
+
+} // namespace detail
+
+// Calculates the side of the intersection-point (if any) of
+// of segment a//b w.r.t. segment c
+// This is calculated without (re)calculating the IP itself again and fully
+// based on integer mathematics; there are no divisions
+// It can be used for either integer (rescaled) points, and also for FP
+class side_of_intersection
+{
+private :
+ template <typename T, typename U>
+ static inline
+ int sign_of_product(T const& a, U const& b)
+ {
+ return a == 0 || b == 0 ? 0
+ : a > 0 && b > 0 ? 1
+ : a < 0 && b < 0 ? 1
+ : -1;
+ }
+
+ template <typename T>
+ static inline
+ int sign_of_compare(T const& a, T const& b, T const& c, T const& d)
+ {
+ // Both a*b and c*d are positive
+ // We have to judge if a*b > c*d
+
+ using side::detail::multiplicable_integral;
+ multiplicable_integral<T> ab = multiplicable_integral<T>(a)
+ * multiplicable_integral<T>(b);
+ multiplicable_integral<T> cd = multiplicable_integral<T>(c)
+ * multiplicable_integral<T>(d);
+
+ int result = ab > cd ? 1
+ : ab < cd ? -1
+ : 0
+ ;
+
+#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
+ using namespace boost::multiprecision;
+ cpp_int const lab = cpp_int(a) * cpp_int(b);
+ cpp_int const lcd = cpp_int(c) * cpp_int(d);
+
+ ab.check_value(lab);
+ cd.check_value(lcd);
+
+ int result2 = lab > lcd ? 1
+ : lab < lcd ? -1
+ : 0
+ ;
+ BOOST_GEOMETRY_ASSERT(result == result2);
+#endif
+
+ return result;
+ }
+
+ template <typename T>
+ static inline
+ int sign_of_addition_of_two_products(T const& a, T const& b, T const& c, T const& d)
+ {
+ // sign of a*b+c*d, 1 if positive, -1 if negative, else 0
+ int const ab = sign_of_product(a, b);
+ int const cd = sign_of_product(c, d);
+ if (ab == 0)
+ {
+ return cd;
+ }
+ if (cd == 0)
+ {
+ return ab;
+ }
+
+ if (ab == cd)
+ {
+ // Both positive or both negative
+ return ab;
+ }
+
+ // One is positive, one is negative, both are non zero
+ // If ab is positive, we have to judge if a*b > -c*d (then 1 because sum is positive)
+ // If ab is negative, we have to judge if c*d > -a*b (idem)
+ return ab == 1
+ ? sign_of_compare(a, b, -c, d)
+ : sign_of_compare(c, d, -a, b);
+ }
+
+
+public :
+
+ // Calculates the side of the intersection-point (if any) of
+ // of segment a//b w.r.t. segment c
+ // This is calculated without (re)calculating the IP itself again and fully
+ // based on integer mathematics
+ template <typename T, typename Segment, typename Point>
+ static inline T side_value(Segment const& a, Segment const& b,
+ Segment const& c, Point const& fallback_point)
+ {
+ // The first point of the three segments is reused several times
+ T const ax = get<0, 0>(a);
+ T const ay = get<0, 1>(a);
+ T const bx = get<0, 0>(b);
+ T const by = get<0, 1>(b);
+ T const cx = get<0, 0>(c);
+ T const cy = get<0, 1>(c);
+
+ T const dx_a = get<1, 0>(a) - ax;
+ T const dy_a = get<1, 1>(a) - ay;
+
+ T const dx_b = get<1, 0>(b) - bx;
+ T const dy_b = get<1, 1>(b) - by;
+
+ T const dx_c = get<1, 0>(c) - cx;
+ T const dy_c = get<1, 1>(c) - cy;
+
+ // Cramer's rule: d (see cart_intersect.hpp)
+ T const d = geometry::detail::determinant<T>
+ (
+ dx_a, dy_a,
+ dx_b, dy_b
+ );
+
+ T const zero = T();
+ if (d == zero)
+ {
+ // There is no IP of a//b, they are collinear or parallel
+ // Assuming they intersect (this method should be called for
+ // segments known to intersect), they are collinear and overlap.
+ // They have one or two intersection points - we don't know and
+ // have to rely on the fallback intersection point
+
+ Point c1, c2;
+ geometry::detail::assign_point_from_index<0>(c, c1);
+ geometry::detail::assign_point_from_index<1>(c, c2);
+ return side_by_triangle<>::apply(c1, c2, fallback_point);
+ }
+
+ // Cramer's rule: da (see cart_intersect.hpp)
+ T const da = geometry::detail::determinant<T>
+ (
+ dx_b, dy_b,
+ ax - bx, ay - by
+ );
+
+ // IP is at (ax + (da/d) * dx_a, ay + (da/d) * dy_a)
+ // Side of IP is w.r.t. c is: determinant(dx_c, dy_c, ipx-cx, ipy-cy)
+ // We replace ipx by expression above and multiply each term by d
+
+#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
+ T const result1 = geometry::detail::determinant<T>
+ (
+ dx_c * d, dy_c * d,
+ d * (ax - cx) + dx_a * da, d * (ay - cy) + dy_a * da
+ );
+
+ // Note: result / (d * d)
+ // is identical to the side_value of side_by_triangle
+ // Therefore, the sign is always the same as that result, and the
+ // resulting side (left,right,collinear) is the same
+
+ // The first row we divide again by d because of determinant multiply rule
+ T const result2 = d * geometry::detail::determinant<T>
+ (
+ dx_c, dy_c,
+ d * (ax - cx) + dx_a * da, d * (ay - cy) + dy_a * da
+ );
+ // Write out:
+ T const result3 = d * (dx_c * (d * (ay - cy) + dy_a * da)
+ - dy_c * (d * (ax - cx) + dx_a * da));
+ // Write out in braces:
+ T const result4 = d * (dx_c * d * (ay - cy) + dx_c * dy_a * da
+ - dy_c * d * (ax - cx) - dy_c * dx_a * da);
+ // Write in terms of d * XX + da * YY
+ T const result5 = d * (d * (dx_c * (ay - cy) - dy_c * (ax - cx))
+ + da * (dx_c * dy_a - dy_c * dx_a));
+
+ boost::ignore_unused(result1, result2, result3, result4, result5);
+ //return result;
+#endif
+
+ // We consider the results separately
+ // (in the end we only have to return the side-value 1,0 or -1)
+
+ // To avoid multiplications we judge the product (easy, avoids *d)
+ // and the sign of p*q+r*s (more elaborate)
+ T const result = sign_of_product
+ (
+ d,
+ sign_of_addition_of_two_products
+ (
+ d, dx_c * (ay - cy) - dy_c * (ax - cx),
+ da, dx_c * dy_a - dy_c * dx_a
+ )
+ );
+ return result;
+
+
+ }
+
+ template <typename Segment, typename Point>
+ static inline int apply(Segment const& a, Segment const& b,
+ Segment const& c,
+ Point const& fallback_point)
+ {
+ typedef typename geometry::coordinate_type<Segment>::type coordinate_type;
+ coordinate_type const s = side_value<coordinate_type>(a, b, c, fallback_point);
+ coordinate_type const zero = coordinate_type();
+ return math::equals(s, zero) ? 0
+ : s > zero ? 1
+ : -1;
+ }
+
+};
+
+
+}} // namespace strategy::side
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_OF_INTERSECTION_HPP
diff --git a/3party/boost/boost/geometry/strategies/comparable_distance_result.hpp b/3party/boost/boost/geometry/strategies/comparable_distance_result.hpp
index a258ddb9b4..5ba9b1603d 100644
--- a/3party/boost/boost/geometry/strategies/comparable_distance_result.hpp
+++ b/3party/boost/boost/geometry/strategies/comparable_distance_result.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -91,9 +91,9 @@ struct comparable_distance_result
// A set of all variant type combinations that are compatible and
// implemented
typedef typename util::combine_if<
- typename mpl::vector1<Geometry1>,
+ typename boost::mpl::vector1<Geometry1>,
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
- mpl::always<mpl::true_>
+ boost::mpl::always<boost::mpl::true_>
>::type possible_input_types;
// The (possibly variant) result type resulting from these combinations
@@ -101,11 +101,11 @@ struct comparable_distance_result
typename transform_variant<
possible_input_types,
resolve_strategy::comparable_distance_result<
- mpl::first<mpl::_>,
- mpl::second<mpl::_>,
+ boost::mpl::first<boost::mpl::_>,
+ boost::mpl::second<boost::mpl::_>,
Strategy
>,
- mpl::back_inserter<mpl::vector0<> >
+ boost::mpl::back_inserter<boost::mpl::vector0<> >
>::type
>::type type;
};
@@ -144,7 +144,7 @@ struct comparable_distance_result
<
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
- mpl::always<mpl::true_>
+ boost::mpl::always<boost::mpl::true_>
>::type possible_input_types;
// The (possibly variant) result type resulting from these combinations
@@ -152,11 +152,11 @@ struct comparable_distance_result
typename transform_variant<
possible_input_types,
resolve_strategy::comparable_distance_result<
- mpl::first<mpl::_>,
- mpl::second<mpl::_>,
+ boost::mpl::first<boost::mpl::_>,
+ boost::mpl::second<boost::mpl::_>,
Strategy
>,
- mpl::back_inserter<mpl::vector0<> >
+ boost::mpl::back_inserter<boost::mpl::vector0<> >
>::type
>::type type;
};
diff --git a/3party/boost/boost/geometry/strategies/concepts/convex_hull_concept.hpp b/3party/boost/boost/geometry/strategies/concepts/convex_hull_concept.hpp
index 80c21423ef..d6e42e95a3 100644
--- a/3party/boost/boost/geometry/strategies/concepts/convex_hull_concept.hpp
+++ b/3party/boost/boost/geometry/strategies/concepts/convex_hull_concept.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -56,7 +61,7 @@ class ConvexHullStrategy
str->apply(*sp, *st);
// 5) must implement a method result, with an output iterator
- str->result(*st, std::back_inserter(*v), true);
+ str->result(*st, std::back_inserter(*v), true, true);
}
};
diff --git a/3party/boost/boost/geometry/strategies/concepts/distance_concept.hpp b/3party/boost/boost/geometry/strategies/concepts/distance_concept.hpp
index a0cbbd21ed..6e75fa95a6 100644
--- a/3party/boost/boost/geometry/strategies/concepts/distance_concept.hpp
+++ b/3party/boost/boost/geometry/strategies/concepts/distance_concept.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -19,6 +24,8 @@
#include <boost/concept_check.hpp>
#include <boost/core/ignore_unused.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/util/parameter_type_of.hpp>
@@ -26,13 +33,15 @@
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+
namespace boost { namespace geometry { namespace concept
{
/*!
- \brief Checks strategy for point-segment-distance
+ \brief Checks strategy for point-point or point-box or box-box distance
\ingroup distance
*/
template <typename Strategy, typename Point1, typename Point2>
@@ -57,7 +66,7 @@ private :
ApplyMethod, 1
>::type ptype2;
- // 2) must define meta-function return_type
+ // 2) must define meta-function "return_type"
typedef typename strategy::distance::services::return_type
<
Strategy, ptype1, ptype2
@@ -75,6 +84,16 @@ private :
Strategy
>::type tag;
+ static const bool is_correct_strategy_tag =
+ boost::is_same<tag, strategy_tag_distance_point_point>::value
+ || boost::is_same<tag, strategy_tag_distance_point_box>::value
+ || boost::is_same<tag, strategy_tag_distance_box_box>::value;
+
+ BOOST_MPL_ASSERT_MSG
+ ((is_correct_strategy_tag),
+ INCORRECT_STRATEGY_TAG,
+ (types<tag>));
+
// 5) must implement apply with arguments
Strategy* str = 0;
ptype1 *p1 = 0;
@@ -111,7 +130,7 @@ public :
/*!
- \brief Checks strategy for point-segment-distance
+ \brief Checks strategy for point-segment distance
\ingroup strategy_concepts
*/
template <typename Strategy, typename Point, typename PointOfSegment>
@@ -125,6 +144,7 @@ private :
template <typename ApplyMethod>
static void apply(ApplyMethod)
{
+ // 1) inspect and define both arguments of apply
typedef typename parameter_type_of
<
ApplyMethod, 0
@@ -135,10 +155,28 @@ private :
ApplyMethod, 1
>::type sptype;
- // must define meta-function return_type
- typedef typename strategy::distance::services::return_type<Strategy, ptype, sptype>::type rtype;
+ namespace services = strategy::distance::services;
+ // 2) must define meta-function "tag"
+ typedef typename services::tag<Strategy>::type tag;
+ BOOST_MPL_ASSERT_MSG
+ ((boost::is_same
+ <
+ tag, strategy_tag_distance_point_segment
+ >::value),
+ INCORRECT_STRATEGY_TAG,
+ (types<tag>));
+ // 3) must define meta-function "return_type"
+ typedef typename services::return_type
+ <
+ Strategy, ptype, sptype
+ >::type rtype;
+
+ // 4) must define meta-function "comparable_type"
+ typedef typename services::comparable_type<Strategy>::type ctype;
+
+ // 5) must implement apply with arguments
Strategy *str = 0;
ptype *p = 0;
sptype *sp1 = 0;
@@ -146,8 +184,16 @@ private :
rtype r = str->apply(*p, *sp1, *sp2);
- boost::ignore_unused_variable_warning(str);
- boost::ignore_unused_variable_warning(r);
+ // 6) must define (meta-)struct "get_comparable" with apply
+ ctype cstrategy = services::get_comparable<Strategy>::apply(*str);
+
+ // 7) must define (meta-)struct "result_from_distance" with apply
+ r = services::result_from_distance
+ <
+ Strategy, ptype, sptype
+ >::apply(*str, rtype(1.0));
+
+ boost::ignore_unused(str, r, cstrategy);
}
};
diff --git a/3party/boost/boost/geometry/strategies/distance_comparable_to_regular.hpp b/3party/boost/boost/geometry/strategies/distance_comparable_to_regular.hpp
deleted file mode 100644
index 88f51eb151..0000000000
--- a/3party/boost/boost/geometry/strategies/distance_comparable_to_regular.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2014, Oracle and/or its affiliates.
-
-// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
-
-// Licensed under the Boost Software License version 1.0.
-// http://www.boost.org/users/license.html
-
-#ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_COMPARABLE_TO_REGULAR_HPP
-#define BOOST_GEOMETRY_STRATEGIES_DISTANCE_COMPARABLE_TO_REGULAR_HPP
-
-#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/core/cs.hpp>
-#include <boost/geometry/algorithms/not_implemented.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-namespace strategy { namespace distance
-{
-
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-namespace services
-{
-
-
-template
-<
- typename ComparableStrategy,
- typename Strategy,
- typename Geometry1,
- typename Geometry2,
- typename CsTag1 = typename cs_tag<Geometry1>::type,
- typename CsTag2 = typename cs_tag<Geometry2>::type
->
-struct comparable_to_regular
- : geometry::not_implemented<CsTag1, CsTag2>
-{};
-
-
-} // namespace services
-#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-
-
-}} // namespace strategy::distance
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_COMPARABLE_TO_REGULAR_HPP
diff --git a/3party/boost/boost/geometry/strategies/distance_result.hpp b/3party/boost/boost/geometry/strategies/distance_result.hpp
index 185a511464..e4f326d3ee 100644
--- a/3party/boost/boost/geometry/strategies/distance_result.hpp
+++ b/3party/boost/boost/geometry/strategies/distance_result.hpp
@@ -1,13 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -100,14 +100,14 @@ struct distance_result
// A set of all variant type combinations that are compatible and
// implemented
typedef typename util::combine_if<
- typename mpl::vector1<Geometry1>,
+ typename boost::mpl::vector1<Geometry1>,
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
// Here we want should remove most of the combinations that
// are not valid, mostly to limit the size of the resulting MPL set.
// But is_implementedn is not ready for prime time
//
- // util::is_implemented2<mpl::_1, mpl::_2, dispatch::distance<mpl::_1, mpl::_2> >
- mpl::always<mpl::true_>
+ // util::is_implemented2<boost::mpl::_1, boost::mpl::_2, dispatch::distance<boost::mpl::_1, boost::mpl::_2> >
+ boost::mpl::always<boost::mpl::true_>
>::type possible_input_types;
// The (possibly variant) result type resulting from these combinations
@@ -115,11 +115,11 @@ struct distance_result
typename transform_variant<
possible_input_types,
resolve_strategy::distance_result<
- mpl::first<mpl::_>,
- mpl::second<mpl::_>,
+ boost::mpl::first<boost::mpl::_>,
+ boost::mpl::second<boost::mpl::_>,
Strategy
>,
- mpl::back_inserter<mpl::vector0<> >
+ boost::mpl::back_inserter<boost::mpl::vector0<> >
>::type
>::type type;
};
@@ -163,8 +163,8 @@ struct distance_result
// resulting MPL vector.
// But is_implemented is not ready for prime time
//
- // util::is_implemented2<mpl::_1, mpl::_2, dispatch::distance<mpl::_1, mpl::_2> >
- mpl::always<mpl::true_>
+ // util::is_implemented2<boost::mpl::_1, boost::mpl::_2, dispatch::distance<boost::mpl::_1, boost::mpl::_2> >
+ boost::mpl::always<boost::mpl::true_>
>::type possible_input_types;
// The (possibly variant) result type resulting from these combinations
@@ -172,11 +172,11 @@ struct distance_result
typename transform_variant<
possible_input_types,
resolve_strategy::distance_result<
- mpl::first<mpl::_>,
- mpl::second<mpl::_>,
+ boost::mpl::first<boost::mpl::_>,
+ boost::mpl::second<boost::mpl::_>,
Strategy
>,
- mpl::back_inserter<mpl::vector0<> >
+ boost::mpl::back_inserter<boost::mpl::vector0<> >
>::type
>::type type;
};
diff --git a/3party/boost/boost/geometry/strategies/geographic/distance_andoyer.hpp b/3party/boost/boost/geometry/strategies/geographic/distance_andoyer.hpp
new file mode 100644
index 0000000000..64de8c1a41
--- /dev/null
+++ b/3party/boost/boost/geometry/strategies/geographic/distance_andoyer.hpp
@@ -0,0 +1,224 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_GEOGRAPHIC_ANDOYER_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ANDOYER_HPP
+
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace distance
+{
+
+
+/*!
+\brief Point-point distance approximation taking flattening into account
+\ingroup distance
+\tparam Spheroid The reference spheroid model
+\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 Spheroid,
+ typename CalculationType = void
+>
+class andoyer
+{
+public :
+ template <typename Point1, typename Point2>
+ struct calculation_type
+ : promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point1,
+ Point2,
+ CalculationType
+ >::type
+ >
+ {};
+
+ typedef Spheroid model_type;
+
+ inline andoyer()
+ : m_spheroid()
+ {}
+
+ explicit inline andoyer(Spheroid const& spheroid)
+ : m_spheroid(spheroid)
+ {}
+
+
+ template <typename Point1, typename Point2>
+ inline typename calculation_type<Point1, Point2>::type
+ apply(Point1 const& point1, Point2 const& point2) const
+ {
+ return calc<typename calculation_type<Point1, Point2>::type>
+ (
+ get_as_radian<0>(point1), get_as_radian<1>(point1),
+ get_as_radian<0>(point2), get_as_radian<1>(point2)
+ );
+ }
+
+ inline Spheroid const& model() const
+ {
+ return m_spheroid;
+ }
+
+private :
+ template <typename CT, typename T>
+ inline CT calc(T const& lon1,
+ T const& lat1,
+ T const& lon2,
+ T const& lat2) const
+ {
+ CT const G = (lat1 - lat2) / 2.0;
+ CT const lambda = (lon1 - lon2) / 2.0;
+
+ if (geometry::math::equals(lambda, 0.0)
+ && geometry::math::equals(G, 0.0))
+ {
+ return 0.0;
+ }
+
+ CT const F = (lat1 + lat2) / 2.0;
+
+ CT const sinG2 = math::sqr(sin(G));
+ CT const cosG2 = math::sqr(cos(G));
+ CT const sinF2 = math::sqr(sin(F));
+ CT const cosF2 = math::sqr(cos(F));
+ CT const sinL2 = math::sqr(sin(lambda));
+ CT const cosL2 = math::sqr(cos(lambda));
+
+ CT const S = sinG2 * cosL2 + cosF2 * sinL2;
+ CT const C = cosG2 * cosL2 + sinF2 * sinL2;
+
+ CT const c0 = 0;
+ CT const c1 = 1;
+ CT const c2 = 2;
+ CT const c3 = 3;
+
+ if (geometry::math::equals(S, c0) || geometry::math::equals(C, c0))
+ {
+ return c0;
+ }
+
+ CT const radius_a = CT(get_radius<0>(m_spheroid));
+ CT const flattening = geometry::detail::flattening<CT>(m_spheroid);
+
+ CT const omega = atan(math::sqrt(S / C));
+ CT const r3 = c3 * math::sqrt(S * C) / omega; // not sure if this is r or greek nu
+ CT const D = c2 * omega * radius_a;
+ CT const H1 = (r3 - c1) / (c2 * C);
+ CT const H2 = (r3 + c1) / (c2 * S);
+
+ return D * (c1 + flattening * (H1 * sinF2 * cosG2 - H2 * cosF2 * sinG2) );
+ }
+
+ Spheroid m_spheroid;
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Spheroid, typename CalculationType>
+struct tag<andoyer<Spheroid, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Spheroid, typename CalculationType, typename P1, typename P2>
+struct return_type<andoyer<Spheroid, CalculationType>, P1, P2>
+ : andoyer<Spheroid, CalculationType>::template calculation_type<P1, P2>
+{};
+
+
+template <typename Spheroid, typename CalculationType>
+struct comparable_type<andoyer<Spheroid, CalculationType> >
+{
+ typedef andoyer<Spheroid, CalculationType> type;
+};
+
+
+template <typename Spheroid, typename CalculationType>
+struct get_comparable<andoyer<Spheroid, CalculationType> >
+{
+ static inline andoyer<Spheroid, CalculationType> apply(andoyer<Spheroid, CalculationType> const& input)
+ {
+ return input;
+ }
+};
+
+template <typename Spheroid, typename CalculationType, typename P1, typename P2>
+struct result_from_distance<andoyer<Spheroid, CalculationType>, P1, P2>
+{
+ template <typename T>
+ static inline typename return_type<andoyer<Spheroid, CalculationType>, P1, P2>::type
+ apply(andoyer<Spheroid, CalculationType> const& , T const& value)
+ {
+ return value;
+ }
+};
+
+
+template <typename Point1, typename Point2>
+struct default_strategy<point_tag, point_tag, Point1, Point2, geographic_tag, geographic_tag>
+{
+ typedef strategy::distance::andoyer
+ <
+ srs::spheroid
+ <
+ typename select_coordinate_type<Point1, Point2>::type
+ >
+ > type;
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ANDOYER_HPP
diff --git a/3party/boost/boost/geometry/strategies/geographic/distance_thomas.hpp b/3party/boost/boost/geometry/strategies/geographic/distance_thomas.hpp
new file mode 100644
index 0000000000..fb9c125982
--- /dev/null
+++ b/3party/boost/boost/geometry/strategies/geographic/distance_thomas.hpp
@@ -0,0 +1,155 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_GEOGRAPHIC_THOMAS_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_THOMAS_HPP
+
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+#include <boost/geometry/algorithms/detail/thomas_inverse.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace distance
+{
+
+/*!
+\brief The solution of the inverse problem of geodesics on latlong coordinates,
+ Forsyth-Andoyer-Lambert type approximation with second order terms.
+\ingroup distance
+\tparam Spheroid The reference spheroid model
+\tparam CalculationType \tparam_calculation
+\author See
+ - Technical Report: PAUL D. THOMAS, MATHEMATICAL MODELS FOR NAVIGATION SYSTEMS, 1965
+ http://www.dtic.mil/docs/citations/AD0627893
+ - Technical Report: PAUL D. THOMAS, SPHEROIDAL GEODESICS, REFERENCE SYSTEMS, AND LOCAL GEOMETRY, 1970
+ http://www.dtic.mil/docs/citations/AD703541
+*/
+template
+<
+ typename Spheroid,
+ typename CalculationType = void
+>
+class thomas
+{
+public :
+ template <typename Point1, typename Point2>
+ struct calculation_type
+ : promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point1,
+ Point2,
+ CalculationType
+ >::type
+ >
+ {};
+
+ typedef Spheroid model_type;
+
+ inline thomas()
+ : m_spheroid()
+ {}
+
+ explicit inline thomas(Spheroid const& spheroid)
+ : m_spheroid(spheroid)
+ {}
+
+ template <typename Point1, typename Point2>
+ inline typename calculation_type<Point1, Point2>::type
+ apply(Point1 const& point1, Point2 const& point2) const
+ {
+ return geometry::detail::thomas_inverse
+ <
+ typename calculation_type<Point1, Point2>::type
+ >(get_as_radian<0>(point1),
+ get_as_radian<1>(point1),
+ get_as_radian<0>(point2),
+ get_as_radian<1>(point2),
+ m_spheroid).distance();
+ }
+
+ inline Spheroid const& model() const
+ {
+ return m_spheroid;
+ }
+
+private :
+ Spheroid m_spheroid;
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Spheroid, typename CalculationType>
+struct tag<thomas<Spheroid, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Spheroid, typename CalculationType, typename P1, typename P2>
+struct return_type<thomas<Spheroid, CalculationType>, P1, P2>
+ : thomas<Spheroid, CalculationType>::template calculation_type<P1, P2>
+{};
+
+
+template <typename Spheroid, typename CalculationType>
+struct comparable_type<thomas<Spheroid, CalculationType> >
+{
+ typedef thomas<Spheroid, CalculationType> type;
+};
+
+
+template <typename Spheroid, typename CalculationType>
+struct get_comparable<thomas<Spheroid, CalculationType> >
+{
+ static inline thomas<Spheroid, CalculationType> apply(thomas<Spheroid, CalculationType> const& input)
+ {
+ return input;
+ }
+};
+
+template <typename Spheroid, typename CalculationType, typename P1, typename P2>
+struct result_from_distance<thomas<Spheroid, CalculationType>, P1, P2 >
+{
+ template <typename T>
+ static inline typename return_type<thomas<Spheroid, CalculationType>, P1, P2>::type
+ apply(thomas<Spheroid, CalculationType> const& , T const& value)
+ {
+ return value;
+ }
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_THOMAS_HPP
diff --git a/3party/boost/boost/geometry/strategies/geographic/distance_vincenty.hpp b/3party/boost/boost/geometry/strategies/geographic/distance_vincenty.hpp
new file mode 100644
index 0000000000..56dd14bbdc
--- /dev/null
+++ b/3party/boost/boost/geometry/strategies/geographic/distance_vincenty.hpp
@@ -0,0 +1,161 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_GEOGRAPHIC_VINCENTY_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_VINCENTY_HPP
+
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+#include <boost/geometry/algorithms/detail/vincenty_inverse.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace distance
+{
+
+/*!
+\brief Distance calculation formulae on latlong coordinates, after Vincenty, 1975
+\ingroup distance
+\tparam Spheroid The reference spheroid model
+\tparam CalculationType \tparam_calculation
+\author See
+ - http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
+ - http://www.icsm.gov.au/gda/gdav2.3.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 Spheroid,
+ typename CalculationType = void
+>
+class vincenty
+{
+public :
+ template <typename Point1, typename Point2>
+ struct calculation_type
+ : promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point1,
+ Point2,
+ CalculationType
+ >::type
+ >
+ {};
+
+ typedef Spheroid model_type;
+
+ inline vincenty()
+ : m_spheroid()
+ {}
+
+ explicit inline vincenty(Spheroid const& spheroid)
+ : m_spheroid(spheroid)
+ {}
+
+ template <typename Point1, typename Point2>
+ inline typename calculation_type<Point1, Point2>::type
+ apply(Point1 const& point1, Point2 const& point2) const
+ {
+ return geometry::detail::vincenty_inverse
+ <
+ typename calculation_type<Point1, Point2>::type
+ >(get_as_radian<0>(point1),
+ get_as_radian<1>(point1),
+ get_as_radian<0>(point2),
+ get_as_radian<1>(point2),
+ m_spheroid).distance();
+ }
+
+ inline Spheroid const& model() const
+ {
+ return m_spheroid;
+ }
+
+private :
+ Spheroid m_spheroid;
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Spheroid, typename CalculationType>
+struct tag<vincenty<Spheroid, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Spheroid, typename CalculationType, typename P1, typename P2>
+struct return_type<vincenty<Spheroid, CalculationType>, P1, P2>
+ : vincenty<Spheroid, CalculationType>::template calculation_type<P1, P2>
+{};
+
+
+template <typename Spheroid, typename CalculationType>
+struct comparable_type<vincenty<Spheroid, CalculationType> >
+{
+ typedef vincenty<Spheroid, CalculationType> type;
+};
+
+
+template <typename Spheroid, typename CalculationType>
+struct get_comparable<vincenty<Spheroid, CalculationType> >
+{
+ static inline vincenty<Spheroid, CalculationType> apply(vincenty<Spheroid, CalculationType> const& input)
+ {
+ return input;
+ }
+};
+
+template <typename Spheroid, typename CalculationType, typename P1, typename P2>
+struct result_from_distance<vincenty<Spheroid, CalculationType>, P1, P2 >
+{
+ template <typename T>
+ static inline typename return_type<vincenty<Spheroid, CalculationType>, P1, P2>::type
+ apply(vincenty<Spheroid, CalculationType> 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_STRATEGIES_GEOGRAPHIC_VINCENTY_HPP
diff --git a/3party/boost/boost/geometry/strategies/geographic/mapping_ssf.hpp b/3party/boost/boost/geometry/strategies/geographic/mapping_ssf.hpp
new file mode 100644
index 0000000000..3beedc7809
--- /dev/null
+++ b/3party/boost/boost/geometry/strategies/geographic/mapping_ssf.hpp
@@ -0,0 +1,185 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_GEOGRAPHIC_MAPPING_SSF_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_MAPPING_SSF_HPP
+
+
+#include <boost/core/ignore_unused.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/spherical/ssf.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace side
+{
+
+
+// An enumeration type defining types of mapping of geographical
+// latitude to spherical latitude.
+// See: http://en.wikipedia.org/wiki/Great_ellipse
+// http://en.wikipedia.org/wiki/Latitude#Auxiliary_latitudes
+enum mapping_type { mapping_geodetic, mapping_reduced, mapping_geocentric };
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Spheroid, mapping_type Mapping>
+struct mapper
+{
+ explicit inline mapper(Spheroid const& /*spheroid*/) {}
+
+ template <typename CalculationType>
+ static inline CalculationType const& apply(CalculationType const& lat)
+ {
+ return lat;
+ }
+};
+
+template <typename Spheroid>
+struct mapper<Spheroid, mapping_reduced>
+{
+ typedef typename promote_floating_point
+ <
+ typename radius_type<Spheroid>::type
+ >::type fraction_type;
+
+ explicit inline mapper(Spheroid const& spheroid)
+ {
+ fraction_type const a = geometry::get_radius<0>(spheroid);
+ fraction_type const b = geometry::get_radius<2>(spheroid);
+ b_div_a = b / a;
+ }
+
+ template <typename CalculationType>
+ inline CalculationType apply(CalculationType const& lat) const
+ {
+ return atan(static_cast<CalculationType>(b_div_a) * tan(lat));
+ }
+
+ fraction_type b_div_a;
+};
+
+template <typename Spheroid>
+struct mapper<Spheroid, mapping_geocentric>
+{
+ typedef typename promote_floating_point
+ <
+ typename radius_type<Spheroid>::type
+ >::type fraction_type;
+
+ explicit inline mapper(Spheroid const& spheroid)
+ {
+ fraction_type const a = geometry::get_radius<0>(spheroid);
+ fraction_type const b = geometry::get_radius<2>(spheroid);
+ sqr_b_div_a = b / a;
+ sqr_b_div_a *= sqr_b_div_a;
+ }
+
+ template <typename CalculationType>
+ inline CalculationType apply(CalculationType const& lat) const
+ {
+ return atan(static_cast<CalculationType>(sqr_b_div_a) * tan(lat));
+ }
+
+ fraction_type sqr_b_div_a;
+};
+
+}
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Check at which side of a geographical segment a point lies
+ left of segment (> 0), right of segment (< 0), on segment (0).
+ The check is performed by mapping the geographical coordinates
+ to spherical coordinates and using spherical_side_formula.
+\ingroup strategies
+\tparam Spheroid The reference spheroid model
+\tparam Mapping The type of mapping of geographical to spherical latitude
+\tparam CalculationType \tparam_calculation
+ */
+template <typename Spheroid,
+ mapping_type Mapping = mapping_geodetic,
+ typename CalculationType = void>
+class mapping_spherical_side_formula
+{
+
+public :
+ inline mapping_spherical_side_formula()
+ : m_mapper(Spheroid())
+ {}
+
+ explicit inline mapping_spherical_side_formula(Spheroid const& spheroid)
+ : m_mapper(spheroid)
+ {}
+
+ template <typename P1, typename P2, typename P>
+ inline int apply(P1 const& p1, P2 const& p2, P const& p)
+ {
+ typedef typename promote_floating_point
+ <
+ typename select_calculation_type_alt
+ <
+ CalculationType,
+ P1, P2, P
+ >::type
+ >::type calculation_type;
+
+ calculation_type lon1 = get_as_radian<0>(p1);
+ calculation_type lat1 = m_mapper.template apply<calculation_type>(get_as_radian<1>(p1));
+ calculation_type lon2 = get_as_radian<0>(p2);
+ calculation_type lat2 = m_mapper.template apply<calculation_type>(get_as_radian<1>(p2));
+ calculation_type lon = get_as_radian<0>(p);
+ calculation_type lat = m_mapper.template apply<calculation_type>(get_as_radian<1>(p));
+
+ return detail::spherical_side_formula(lon1, lat1, lon2, lat2, lon, lat);
+ }
+
+private:
+ side::detail::mapper<Spheroid, Mapping> const m_mapper;
+};
+
+// The specialization for geodetic latitude which can be used directly
+template <typename Spheroid,
+ typename CalculationType>
+class mapping_spherical_side_formula<Spheroid, mapping_geodetic, CalculationType>
+{
+
+public :
+ inline mapping_spherical_side_formula() {}
+ explicit inline mapping_spherical_side_formula(Spheroid const& /*spheroid*/) {}
+
+ template <typename P1, typename P2, typename P>
+ static inline int apply(P1 const& p1, P2 const& p2, P const& p)
+ {
+ return spherical_side_formula<CalculationType>::apply(p1, p2, p);
+ }
+};
+
+}} // namespace strategy::side
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_MAPPING_SSF_HPP
diff --git a/3party/boost/boost/geometry/strategies/geographic/side_andoyer.hpp b/3party/boost/boost/geometry/strategies/geographic/side_andoyer.hpp
new file mode 100644
index 0000000000..e0f0c04067
--- /dev/null
+++ b/3party/boost/boost/geometry/strategies/geographic/side_andoyer.hpp
@@ -0,0 +1,55 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_GEOGRAPHIC_SIDE_ANDOYER_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_ANDOYER_HPP
+
+
+#include <boost/geometry/algorithms/detail/andoyer_inverse.hpp>
+
+#include <boost/geometry/strategies/geographic/side_detail.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 Model Reference model of coordinate system.
+\tparam CalculationType \tparam_calculation
+ */
+template <typename Model, typename CalculationType = void>
+class andoyer
+ : public detail::by_azimuth<geometry::detail::andoyer_inverse, Model, CalculationType>
+{
+ typedef detail::by_azimuth<geometry::detail::andoyer_inverse, Model, CalculationType> base_t;
+
+public:
+ andoyer(Model const& model = Model())
+ : base_t(model)
+ {}
+};
+
+}} // namespace strategy::side
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_ANDOYER_HPP
diff --git a/3party/boost/boost/geometry/strategies/geographic/side_detail.hpp b/3party/boost/boost/geometry/strategies/geographic/side_detail.hpp
new file mode 100644
index 0000000000..1c6634c9f4
--- /dev/null
+++ b/3party/boost/boost/geometry/strategies/geographic/side_detail.hpp
@@ -0,0 +1,137 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_GEOGRAPHIC_SIDE_DETAIL_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_DETAIL_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/radius.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.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
+{
+
+/*!
+\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 InverseFormula Geodesic inverse solution formula.
+\tparam Model Reference model of coordinate system.
+\tparam CalculationType \tparam_calculation
+ */
+template <template<typename> class InverseFormula,
+ typename Model,
+ typename CalculationType = void>
+class by_azimuth
+{
+public:
+ by_azimuth(Model const& model = Model())
+ : m_model(model)
+ {}
+
+ template <typename P1, typename P2, typename P>
+ inline int apply(P1 const& p1, P2 const& p2, P const& p)
+ {
+ typedef typename promote_floating_point
+ <
+ typename select_calculation_type_alt
+ <
+ CalculationType,
+ P1, P2, P
+ >::type
+ >::type calc_t;
+
+ calc_t a1p = azimuth< calc_t, InverseFormula<calc_t> >(p1, p, m_model);
+ calc_t a12 = azimuth< calc_t, InverseFormula<calc_t> >(p1, p2, m_model);
+
+ calc_t const pi = math::pi<calc_t>();
+
+ // instead of the formula from XTD
+ //calc_t a_diff = asin(sin(a1p - a12));
+
+ calc_t a_diff = a1p - a12;
+ // normalize, angle in [-pi, pi]
+ while ( a_diff > pi )
+ a_diff -= calc_t(2) * pi;
+ while ( a_diff < -pi )
+ a_diff += calc_t(2) * pi;
+
+ // NOTE: in general it shouldn't be required to support the pi/-pi case
+ // because in non-cartesian systems it makes sense to check the side
+ // only "between" the endpoints.
+ // However currently the winding strategy calls the side strategy
+ // for vertical segments to check if the point is "between the endpoints.
+ // This could be avoided since the side strategy is not required for that
+ // because meridian is the shortest path. So a difference of
+ // longitudes would be sufficient (of course normalized to [-pi, pi]).
+
+ // NOTE: with the above said, the pi/-pi check is temporary
+ // however in case if this was required
+ // the geodesics on ellipsoid aren't "symmetrical"
+ // therefore instead of comparing a_diff to pi and -pi
+ // one should probably use inverse azimuths and compare
+ // the difference to 0 as well
+
+ // positive azimuth is on the right side
+ return math::equals(a_diff, 0)
+ || math::equals(a_diff, pi)
+ || math::equals(a_diff, -pi) ? 0
+ : a_diff > 0 ? -1 // right
+ : 1; // left
+ }
+
+private:
+ template <typename ResultType,
+ typename InverseFormulaType,
+ typename Point1,
+ typename Point2,
+ typename ModelT>
+ static inline ResultType azimuth(Point1 const& point1, Point2 const& point2, ModelT const& model)
+ {
+ return InverseFormulaType(get_as_radian<0>(point1),
+ get_as_radian<1>(point1),
+ get_as_radian<0>(point2),
+ get_as_radian<1>(point2),
+ model).azimuth();
+ }
+
+ Model m_model;
+};
+
+} // detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace strategy::side
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_DETAIL_HPP
diff --git a/3party/boost/boost/geometry/strategies/geographic/side_thomas.hpp b/3party/boost/boost/geometry/strategies/geographic/side_thomas.hpp
new file mode 100644
index 0000000000..a96cabdaab
--- /dev/null
+++ b/3party/boost/boost/geometry/strategies/geographic/side_thomas.hpp
@@ -0,0 +1,55 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_GEOGRAPHIC_SIDE_THOMAS_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_THOMAS_HPP
+
+
+#include <boost/geometry/algorithms/detail/thomas_inverse.hpp>
+
+#include <boost/geometry/strategies/geographic/side_detail.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 Model Reference model of coordinate system.
+\tparam CalculationType \tparam_calculation
+ */
+template <typename Model, typename CalculationType = void>
+class thomas
+ : public detail::by_azimuth<geometry::detail::thomas_inverse, Model, CalculationType>
+{
+ typedef detail::by_azimuth<geometry::detail::thomas_inverse, Model, CalculationType> base_t;
+
+public:
+ thomas(Model const& model = Model())
+ : base_t(model)
+ {}
+};
+
+}} // namespace strategy::side
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_THOMAS_HPP
diff --git a/3party/boost/boost/geometry/strategies/geographic/side_vincenty.hpp b/3party/boost/boost/geometry/strategies/geographic/side_vincenty.hpp
new file mode 100644
index 0000000000..a8ef9550d6
--- /dev/null
+++ b/3party/boost/boost/geometry/strategies/geographic/side_vincenty.hpp
@@ -0,0 +1,55 @@
+// Boost.Geometry
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_GEOGRAPHIC_SIDE_VINCENTY_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_VINCENTY_HPP
+
+
+#include <boost/geometry/algorithms/detail/vincenty_inverse.hpp>
+
+#include <boost/geometry/strategies/geographic/side_detail.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 Model Reference model of coordinate system.
+\tparam CalculationType \tparam_calculation
+ */
+template <typename Model, typename CalculationType = void>
+class vincenty
+ : public detail::by_azimuth<geometry::detail::vincenty_inverse, Model, CalculationType>
+{
+ typedef detail::by_azimuth<geometry::detail::vincenty_inverse, Model, CalculationType> base_t;
+
+public:
+ vincenty(Model const& model = Model())
+ : base_t(model)
+ {}
+};
+
+}} // namespace strategy::side
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_SIDE_VINCENTY_HPP
diff --git a/3party/boost/boost/geometry/strategies/intersection_result.hpp b/3party/boost/boost/geometry/strategies/intersection_result.hpp
index 695db79c9c..062c289de8 100644
--- a/3party/boost/boost/geometry/strategies/intersection_result.hpp
+++ b/3party/boost/boost/geometry/strategies/intersection_result.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,140 +25,6 @@
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 SegmentRatio>
struct fraction_type
{
diff --git a/3party/boost/boost/geometry/strategies/spherical/area_huiller.hpp b/3party/boost/boost/geometry/strategies/spherical/area_huiller.hpp
index e55fdb2b0e..37d8d20124 100644
--- a/3party/boost/boost/geometry/strategies/spherical/area_huiller.hpp
+++ b/3party/boost/boost/geometry/strategies/spherical/area_huiller.hpp
@@ -1,6 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -31,18 +37,22 @@ namespace strategy { namespace area
\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://webdocs.cs.ualberta.ca/~graphics/books/GraphicsGems/gemsiv/sph_poly.c
+- http://tog.acm.org/resources/GraphicsGems/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 The version in Graphics Gems IV (page 132-137) didn't account for
+polygons crossing the 0 and 180 meridians. The fix for this algorithm
+can be found in Graphics Gems V (pages 45-46). See:
+- http://kysmykseka.net/koti/wizardry/Game%20Development/Programming/Graphics%20Gems%204.pdf
+- http://kysmykseka.net/koti/wizardry/Game%20Development/Programming/Graphics%20Gems%205.pdf
\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 The version which sums longitudes, see http://hdl.handle.net/2014/40409,
+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
@@ -113,8 +123,12 @@ public :
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>();
+ calculation_type const pi
+ = geometry::math::pi<calculation_type>();
+ calculation_type const two_pi
+ = geometry::math::two_pi<calculation_type>();
+ calculation_type const half_pi
+ = geometry::math::half_pi<calculation_type>();
// Distance p1 p2
calculation_type a = state.distance_over_unit_sphere.apply(p1, p2);
@@ -128,33 +142,31 @@ public :
// 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
+ calculation_type excess = four
* atan(geometry::math::sqrt(geometry::math::abs(tan(s / two)
* tan((s - a) / two)
* tan((s - b) / two)
* tan((s - c) / two))));
- E = geometry::math::abs(E);
+ excess = geometry::math::abs(excess);
// 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,
+ // Longitude comparisons are not so obvious. If one is negative and 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);
+ calculation_type lon_diff = geometry::get_as_radian<0>(p2)
+ - geometry::get_as_radian<0>(p1);
+ if (lon_diff <= 0)
+ {
+ lon_diff += two_pi;
+ }
- if (lon2 < lon1)
+ if (lon_diff > pi)
{
- E = -E;
+ excess = -excess;
}
- state.sum += E;
+ state.sum += excess;
}
}
diff --git a/3party/boost/boost/geometry/strategies/spherical/distance_cross_track.hpp b/3party/boost/boost/geometry/strategies/spherical/distance_cross_track.hpp
index 6ffa4ff7c8..31993e76cc 100644
--- a/3party/boost/boost/geometry/strategies/spherical/distance_cross_track.hpp
+++ b/3party/boost/boost/geometry/strategies/spherical/distance_cross_track.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,54 +14,315 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
+#include <algorithm>
#include <boost/config.hpp>
#include <boost/concept_check.hpp>
#include <boost/mpl/if.hpp>
-#include <boost/type_traits.hpp>
+#include <boost/type_traits/is_void.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/algorithms/detail/course.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/concepts/distance_concept.hpp>
#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
-#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.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, for points on a sphere or globe
-\see http://williams.best.vwh.net/avform.htm
-\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)]
-}
+namespace comparable
+{
+/*
+ Given a spherical segment AB and a point D, we are interested in
+ computing the distance of D from AB. This is usually known as the
+ cross track distance.
+
+ If the projection (along great circles) of the point D lies inside
+ the segment AB, then the distance (cross track error) XTD is given
+ by the formula (see http://williams.best.vwh.net/avform.htm#XTE):
+
+ XTD = asin( sin(dist_AD) * sin(crs_AD-crs_AB) )
+
+ where dist_AD is the great circle distance between the points A and
+ B, and crs_AD, crs_AB is the course (bearing) between the points A,
+ D and A, B, respectively.
+
+ If the point D does not project inside the arc AB, then the distance
+ of D from AB is the minimum of the two distances dist_AD and dist_BD.
+
+ Our reference implementation for this procedure is listed below
+ (this was the old Boost.Geometry implementation of the cross track distance),
+ where:
+ * The member variable m_strategy is the underlying haversine strategy.
+ * p stands for the point D.
+ * sp1 stands for the segment endpoint A.
+ * sp2 stands for the segment endpoint B.
+
+ ================= reference implementation -- start =================
+
+ return_type d1 = m_strategy.apply(sp1, p);
+ return_type d3 = m_strategy.apply(sp1, sp2);
+
+ if (geometry::math::equals(d3, 0.0))
+ {
+ // "Degenerate" segment, return either d1 or d2
+ return d1;
+ }
+
+ return_type d2 = m_strategy.apply(sp2, p);
+
+ return_type crs_AD = geometry::detail::course<return_type>(sp1, p);
+ return_type crs_AB = geometry::detail::course<return_type>(sp1, sp2);
+ return_type crs_BA = crs_AB - geometry::math::pi<return_type>();
+ return_type crs_BD = geometry::detail::course<return_type>(sp2, p);
+ return_type d_crs1 = crs_AD - crs_AB;
+ return_type d_crs2 = crs_BD - crs_BA;
+
+ // d1, d2, d3 are in principle not needed, only the sign matters
+ return_type projection1 = cos( d_crs1 ) * d1 / d3;
+ return_type projection2 = cos( d_crs2 ) * d2 / d3;
+
+ if (projection1 > 0.0 && projection2 > 0.0)
+ {
+ return_type XTD
+ = radius() * math::abs( asin( sin( d1 / radius() ) * sin( d_crs1 ) ));
+
+ // Return shortest distance, projected point on segment sp1-sp2
+ return return_type(XTD);
+ }
+ else
+ {
+ // Return shortest distance, project either on point sp1 or sp2
+ return return_type( (std::min)( d1 , d2 ) );
+ }
+
+ ================= reference implementation -- end =================
+
+
+ Motivation
+ ----------
+ In what follows we develop a comparable version of the cross track
+ distance strategy, that meets the following goals:
+ * It is more efficient than the original cross track strategy (less
+ operations and less calls to mathematical functions).
+ * Distances using the comparable cross track strategy can not only
+ be compared with other distances using the same strategy, but also with
+ distances computed with the comparable version of the haversine strategy.
+ * It can serve as the basis for the computation of the cross track distance,
+ as it is more efficient to compute its comparable version and
+ transform that to the actual cross track distance, rather than
+ follow/use the reference implementation listed above.
+
+ Major idea
+ ----------
+ The idea here is to use the comparable haversine strategy to compute
+ the distances d1, d2 and d3 in the above listing. Once we have done
+ that we need also to make sure that instead of returning XTD (as
+ computed above) that we return a distance CXTD that is compatible
+ with the comparable haversine distance. To achieve this CXTD must satisfy
+ the relation:
+ XTD = 2 * R * asin( sqrt(XTD) )
+ where R is the sphere's radius.
+
+ Below we perform the mathematical analysis that show how to compute CXTD.
+
+
+ Mathematical analysis
+ ---------------------
+ Below we use the following trigonometric identities:
+ sin(2 * x) = 2 * sin(x) * cos(x)
+ cos(asin(x)) = sqrt(1 - x^2)
+
+ Observation:
+ The distance d1 needed when the projection of the point D is within the
+ segment must be the true distance. However, comparable::haversine<>
+ returns a comparable distance instead of the one needed.
+ To remedy this, we implicitly compute what is needed.
+ More precisely, we need to compute sin(true_d1):
+
+ sin(true_d1) = sin(2 * asin(sqrt(d1)))
+ = 2 * sin(asin(sqrt(d1)) * cos(asin(sqrt(d1)))
+ = 2 * sqrt(d1) * sqrt(1-(sqrt(d1))^2)
+ = 2 * sqrt(d1 - d1 * d1)
+ This relation is used below.
+
+ As we mentioned above the goal is to find CXTD (named "a" below for
+ brevity) such that ("b" below stands for "d1", and "c" for "d_crs1"):
+
+ 2 * R * asin(sqrt(a)) == R * asin(2 * sqrt(b-b^2) * sin(c))
+
+ Analysis:
+ 2 * R * asin(sqrt(a)) == R * asin(2 * sqrt(b-b^2) * sin(c))
+ <=> 2 * asin(sqrt(a)) == asin(sqrt(b-b^2) * sin(c))
+ <=> sin(2 * asin(sqrt(a))) == 2 * sqrt(b-b^2) * sin(c)
+ <=> 2 * sin(asin(sqrt(a))) * cos(asin(sqrt(a))) == 2 * sqrt(b-b^2) * sin(c)
+ <=> 2 * sqrt(a) * sqrt(1-a) == 2 * sqrt(b-b^2) * sin(c)
+ <=> sqrt(a) * sqrt(1-a) == sqrt(b-b^2) * sin(c)
+ <=> sqrt(a-a^2) == sqrt(b-b^2) * sin(c)
+ <=> a-a^2 == (b-b^2) * (sin(c))^2
+
+ Consider the quadratic equation: x^2-x+p^2 == 0,
+ where p = sqrt(b-b^2) * sin(c); its discriminant is:
+ d = 1 - 4 * p^2 = 1 - 4 * (b-b^2) * (sin(c))^2
+
+ The two solutions are:
+ a_1 = (1 - sqrt(d)) / 2
+ a_2 = (1 + sqrt(d)) / 2
+
+ Which one to choose?
+ "a" refers to the distance (on the unit sphere) of D from the
+ supporting great circle Circ(A,B) of the segment AB.
+ The two different values for "a" correspond to the lengths of the two
+ arcs delimited D and the points of intersection of Circ(A,B) and the
+ great circle perperdicular to Circ(A,B) passing through D.
+ Clearly, the value we want is the smallest among these two distances,
+ hence the root we must choose is the smallest root among the two.
+
+ So the answer is:
+ CXTD = ( 1 - sqrt(1 - 4 * (b-b^2) * (sin(c))^2) ) / 2
+
+ Therefore, in order to implement the comparable version of the cross
+ track strategy we need to:
+ (1) Use the comparable version of the haversine strategy instead of
+ the non-comparable one.
+ (2) Instead of return XTD when D projects inside the segment AB, we
+ need to return CXTD, given by the following formula:
+ CXTD = ( 1 - sqrt(1 - 4 * (d1-d1^2) * (sin(d_crs1))^2) ) / 2;
+
+
+ Complexity Analysis
+ -------------------
+ In the analysis that follows we refer to the actual implementation below.
+ In particular, instead of computing CXTD as above, we use the more
+ efficient (operation-wise) computation of CXTD shown here:
+
+ return_type sin_d_crs1 = sin(d_crs1);
+ return_type d1_x_sin = d1 * sin_d_crs1;
+ return_type d = d1_x_sin * (sin_d_crs1 - d1_x_sin);
+ return d / (0.5 + math::sqrt(0.25 - d));
+
+ Notice that instead of computing:
+ 0.5 - 0.5 * sqrt(1 - 4 * d) = 0.5 - sqrt(0.25 - d)
+ we use the following formula instead:
+ d / (0.5 + sqrt(0.25 - d)).
+ This is done for numerical robustness. The expression 0.5 - sqrt(0.25 - x)
+ has large numerical errors for values of x close to 0 (if using doubles
+ the error start to become large even when d is as large as 0.001).
+ To remedy that, we re-write 0.5 - sqrt(0.25 - x) as:
+ 0.5 - sqrt(0.25 - d)
+ = (0.5 - sqrt(0.25 - d) * (0.5 - sqrt(0.25 - d)) / (0.5 + sqrt(0.25 - d)).
+ The numerator is the difference of two squares:
+ (0.5 - sqrt(0.25 - d) * (0.5 - sqrt(0.25 - d))
+ = 0.5^2 - (sqrt(0.25 - d))^ = 0.25 - (0.25 - d) = d,
+ which gives the expression we use.
+
+ For the complexity analysis, we distinguish between two cases:
+ (A) The distance is realized between the point D and an
+ endpoint of the segment AB
+
+ Gains:
+ Since we are using comparable::haversine<> which is called
+ 3 times, we gain:
+ -> 3 calls to sqrt
+ -> 3 calls to asin
+ -> 6 multiplications
+
+ Loses: None
+
+ So the net gain is:
+ -> 6 function calls (sqrt/asin)
+ -> 6 arithmetic operations
+
+ If we use comparable::cross_track<> to compute
+ cross_track<> we need to account for a call to sqrt, a call
+ to asin and 2 multiplications. In this case the net gain is:
+ -> 4 function calls (sqrt/asin)
+ -> 4 arithmetic operations
+
+
+ (B) The distance is realized between the point D and an
+ interior point of the segment AB
+
+ Gains:
+ Since we are using comparable::haversine<> which is called
+ 3 times, we gain:
+ -> 3 calls to sqrt
+ -> 3 calls to asin
+ -> 6 multiplications
+ Also we gain the operations used to compute XTD:
+ -> 2 calls to sin
+ -> 1 call to asin
+ -> 1 call to abs
+ -> 2 multiplications
+ -> 1 division
+ So the total gains are:
+ -> 9 calls to sqrt/sin/asin
+ -> 1 call to abs
+ -> 8 multiplications
+ -> 1 division
+
+ Loses:
+ To compute a distance compatible with comparable::haversine<>
+ we need to perform a few more operations, namely:
+ -> 1 call to sin
+ -> 1 call to sqrt
+ -> 2 multiplications
+ -> 1 division
+ -> 1 addition
+ -> 2 subtractions
+
+ So roughly speaking the net gain is:
+ -> 8 fewer function calls and 3 fewer arithmetic operations
+
+ If we were to implement cross_track directly from the
+ comparable version (much like what haversine<> does using
+ comparable::haversine<>) we need additionally
+ -> 2 function calls (asin/sqrt)
+ -> 2 multiplications
+
+ So it pays off to re-implement cross_track<> to use
+ comparable::cross_track<>; in this case the net gain would be:
+ -> 6 function calls
+ -> 1 arithmetic operation
+
+ Summary/Conclusion
+ ------------------
+ Following the mathematical and complexity analysis above, the
+ comparable cross track strategy (as implemented below) satisfies
+ all the goal mentioned in the beginning:
+ * It is more efficient than its non-comparable counter-part.
+ * Comparable distances using this new strategy can also be compared
+ with comparable distances computed with the comparable haversine
+ strategy.
+ * It turns out to be more efficient to compute the actual cross
+ track distance XTD by first computing CXTD, and then computing
+ XTD by means of the formula:
+ XTD = 2 * R * asin( sqrt(CXTD) )
*/
+
template
<
typename CalculationType = void,
- typename Strategy = haversine<double, CalculationType>
+ typename Strategy = comparable::haversine<double, CalculationType>
>
class cross_track
{
@@ -105,6 +371,19 @@ public :
typedef typename return_type<Point, PointOfSegment>::type return_type;
+#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
+ std::cout << "Course " << dsv(sp1) << " to " << dsv(p) << " "
+ << crs_AD * geometry::math::r2d<return_type>() << std::endl;
+ std::cout << "Course " << dsv(sp1) << " to " << dsv(sp2) << " "
+ << crs_AB * geometry::math::r2d<return_type>() << std::endl;
+ std::cout << "Course " << dsv(sp2) << " to " << dsv(p) << " "
+ << crs_BD * geometry::math::r2d << std::endl;
+ std::cout << "Projection AD-AB " << projection1 << " : "
+ << d_crs1 * geometry::math::r2d<return_type>() << std::endl;
+ std::cout << "Projection BD-BA " << projection2 << " : "
+ << d_crs2 * geometry::math::r2d<return_type>() << std::endl;
+#endif
+
// http://williams.best.vwh.net/avform.htm#XTE
return_type d1 = m_strategy.apply(sp1, p);
return_type d3 = m_strategy.apply(sp1, sp2);
@@ -117,10 +396,10 @@ public :
return_type d2 = m_strategy.apply(sp2, p);
- return_type crs_AD = course(sp1, p);
- return_type crs_AB = course(sp1, sp2);
+ return_type crs_AD = geometry::detail::course<return_type>(sp1, p);
+ return_type crs_AB = geometry::detail::course<return_type>(sp1, sp2);
return_type crs_BA = crs_AB - geometry::math::pi<return_type>();
- return_type crs_BD = course(sp2, p);
+ return_type crs_BD = geometry::detail::course<return_type>(sp2, p);
return_type d_crs1 = crs_AD - crs_AB;
return_type d_crs2 = crs_BD - crs_BA;
@@ -128,25 +407,34 @@ public :
return_type projection1 = cos( d_crs1 ) * d1 / d3;
return_type projection2 = cos( d_crs2 ) * d2 / d3;
-#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 << "Course " << dsv(sp2) << " to " << dsv(p) << " " << crs_BD * geometry::math::r2d << std::endl;
- std::cout << "Projection AD-AB " << projection1 << " : " << d_crs1 * geometry::math::r2d << std::endl;
- std::cout << "Projection BD-BA " << projection2 << " : " << d_crs2 * geometry::math::r2d << std::endl;
-#endif
-
- if(projection1 > 0.0 && projection2 > 0.0)
+ if (projection1 > 0.0 && projection2 > 0.0)
{
- return_type XTD = radius() * geometry::math::abs( asin( sin( d1 / radius() ) * sin( d_crs1 ) ));
+#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
+ return_type XTD = radius() * geometry::math::abs( asin( sin( d1 ) * sin( d_crs1 ) ));
- #ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
std::cout << "Projection ON the segment" << std::endl;
- std::cout << "XTD: " << XTD << " d1: " << d1 << " d2: " << d2 << std::endl;
+ std::cout << "XTD: " << XTD
+ << " d1: " << (d1 * radius())
+ << " d2: " << (d2 * radius())
+ << std::endl;
#endif
-
- // Return shortest distance, projected point on segment sp1-sp2
- return return_type(XTD);
+ return_type const half(0.5);
+ return_type const quarter(0.25);
+
+ return_type sin_d_crs1 = sin(d_crs1);
+ /*
+ This is the straightforward obvious way to continue:
+
+ return_type discriminant
+ = 1.0 - 4.0 * (d1 - d1 * d1) * sin_d_crs1 * sin_d_crs1;
+ return 0.5 - 0.5 * math::sqrt(discriminant);
+
+ Below we optimize the number of arithmetic operations
+ and account for numerical robustness:
+ */
+ return_type d1_x_sin = d1 * sin_d_crs1;
+ return_type d = d1_x_sin * (sin_d_crs1 - d1_x_sin);
+ return d / (half + math::sqrt(quarter - d));
}
else
{
@@ -163,26 +451,97 @@ public :
{ return m_strategy.radius(); }
private :
-
Strategy m_strategy;
+};
+
+} // namespace comparable
+
+
+/*!
+\brief Strategy functor for distance point to segment calculation
+\ingroup strategies
+\details Class which calculates the distance of a point to a segment, for points on a sphere or globe
+\see http://williams.best.vwh.net/avform.htm
+\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 CalculationType = void,
+ typename Strategy = haversine<double, CalculationType>
+>
+class cross_track
+{
+public :
+ template <typename Point, typename PointOfSegment>
+ struct return_type
+ : promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point,
+ PointOfSegment,
+ CalculationType
+ >::type
+ >
+ {};
+
+ inline cross_track()
+ {}
+
+ explicit inline cross_track(typename Strategy::radius_type const& r)
+ : m_strategy(r)
+ {}
+
+ inline cross_track(Strategy const& s)
+ : m_strategy(s)
+ {}
+
+
+ // It might be useful in the future
+ // to overload constructor with strategy info.
+ // crosstrack(...) {}
+
- /// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
- template <typename Point1, typename Point2>
- inline typename return_type<Point1, Point2>::type
- course(Point1 const& p1, Point2 const& p2) const
+ template <typename Point, typename PointOfSegment>
+ inline typename return_type<Point, PointOfSegment>::type
+ apply(Point const& p, PointOfSegment const& sp1, PointOfSegment const& sp2) const
{
- typedef typename return_type<Point1, Point2>::type return_type;
- // 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));
+#if !defined(BOOST_MSVC)
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::PointDistanceStrategy<Strategy, Point, PointOfSegment>)
+ );
+#endif
+ typedef typename return_type<Point, PointOfSegment>::type return_type;
+ typedef cross_track<CalculationType, Strategy> this_type;
+
+ typedef typename services::comparable_type
+ <
+ this_type
+ >::type comparable_type;
- // "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));
+ comparable_type cstrategy
+ = services::get_comparable<this_type>::apply(m_strategy);
+
+ return_type const a = cstrategy.apply(p, sp1, sp2);
+ return_type const c = return_type(2.0) * asin(math::sqrt(a));
+ return c * radius();
}
+ inline typename Strategy::radius_type radius() const
+ { return m_strategy.radius(); }
+
+private :
+
+ Strategy m_strategy;
};
@@ -207,8 +566,10 @@ struct return_type<cross_track<CalculationType, Strategy>, P, PS>
template <typename CalculationType, typename Strategy>
struct comparable_type<cross_track<CalculationType, Strategy> >
{
- // There is no shortcut, so the strategy itself is its comparable type
- typedef cross_track<CalculationType, Strategy> type;
+ typedef comparable::cross_track
+ <
+ CalculationType, typename comparable_type<Strategy>::type
+ > type;
};
@@ -224,7 +585,8 @@ struct get_comparable<cross_track<CalculationType, Strategy> >
cross_track<CalculationType, Strategy>
>::type comparable_type;
public :
- static inline comparable_type apply(cross_track<CalculationType, Strategy> const& strategy)
+ static inline comparable_type
+ apply(cross_track<CalculationType, Strategy> const& strategy)
{
return comparable_type(strategy.radius());
}
@@ -235,21 +597,95 @@ template
<
typename CalculationType,
typename Strategy,
- typename P, typename PS
+ typename P,
+ typename PS
>
struct result_from_distance<cross_track<CalculationType, Strategy>, P, PS>
{
private :
- typedef typename cross_track<CalculationType, Strategy>::template return_type<P, PS> return_type;
+ typedef typename cross_track
+ <
+ CalculationType, Strategy
+ >::template return_type<P, PS>::type return_type;
public :
template <typename T>
- static inline return_type apply(cross_track<CalculationType, Strategy> const& , T const& distance)
+ static inline return_type
+ apply(cross_track<CalculationType, Strategy> const& , T const& distance)
{
return distance;
}
};
+// Specializations for comparable::cross_track
+template <typename RadiusType, typename CalculationType>
+struct tag<comparable::cross_track<RadiusType, CalculationType> >
+{
+ typedef strategy_tag_distance_point_segment type;
+};
+
+
+template
+<
+ typename RadiusType,
+ typename CalculationType,
+ typename P,
+ typename PS
+>
+struct return_type<comparable::cross_track<RadiusType, CalculationType>, P, PS>
+ : comparable::cross_track
+ <
+ RadiusType, CalculationType
+ >::template return_type<P, PS>
+{};
+
+
+template <typename RadiusType, typename CalculationType>
+struct comparable_type<comparable::cross_track<RadiusType, CalculationType> >
+{
+ typedef comparable::cross_track<RadiusType, CalculationType> type;
+};
+
+
+template <typename RadiusType, typename CalculationType>
+struct get_comparable<comparable::cross_track<RadiusType, CalculationType> >
+{
+private :
+ typedef comparable::cross_track<RadiusType, CalculationType> this_type;
+public :
+ static inline this_type apply(this_type const& input)
+ {
+ return input;
+ }
+};
+
+
+template
+<
+ typename RadiusType,
+ typename CalculationType,
+ typename P,
+ typename PS
+>
+struct result_from_distance
+ <
+ comparable::cross_track<RadiusType, CalculationType>, P, PS
+ >
+{
+private :
+ typedef comparable::cross_track<RadiusType, CalculationType> strategy_type;
+ typedef typename return_type<strategy_type, P, PS>::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.0) );
+ return s * s;
+ }
+};
+
/*
@@ -326,17 +762,8 @@ struct default_strategy
} // 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/3party/boost/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp b/3party/boost/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp
new file mode 100644
index 0000000000..fe32f77236
--- /dev/null
+++ b/3party/boost/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp
@@ -0,0 +1,287 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_POINT_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_POINT_BOX_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/calculation_type.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace distance
+{
+
+template
+<
+ typename CalculationType = void,
+ typename Strategy = haversine<double, CalculationType>
+>
+class cross_track_point_box
+{
+public:
+ template <typename Point, typename Box>
+ struct return_type
+ : promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point,
+ typename point_type<Box>::type,
+ CalculationType
+ >::type
+ >
+ {};
+
+ inline cross_track_point_box()
+ {}
+
+ explicit inline cross_track_point_box(typename Strategy::radius_type const& r)
+ : m_pp_strategy(r)
+ {}
+
+ inline cross_track_point_box(Strategy const& s)
+ : m_pp_strategy(s)
+ {}
+
+ template <typename Point, typename Box>
+ inline typename return_type<Point, Box>::type
+ apply(Point const& point, Box const& box) const
+ {
+
+#if !defined(BOOST_MSVC)
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::PointDistanceStrategy
+ <
+ Strategy, Point,
+ typename point_type<Box>::type
+ >)
+ );
+#endif
+
+ typedef typename return_type<Point, Box>::type return_type;
+ typedef typename point_type<Box>::type box_point_t;
+
+ // Create (counterclockwise) array of points, the fifth one closes it
+ // If every point is on the LEFT side (=1) or ON the border (=0)
+ // the distance should be equal to 0.
+
+ // TODO: This strategy as well as other cross-track strategies
+ // and therefore e.g. spherical within(Point, Box) may not work
+ // properly for a Box degenerated to a Segment or Point
+
+ boost::array<box_point_t, 5> bp;
+ geometry::detail::assign_box_corners_oriented<true>(box, bp);
+ bp[4] = bp[0];
+
+ for (int i = 1; i < 5; i++)
+ {
+ box_point_t const& p1 = bp[i - 1];
+ box_point_t const& p2 = bp[i];
+
+ return_type const crs_AD = geometry::detail::course<return_type>(p1, point);
+ return_type const crs_AB = geometry::detail::course<return_type>(p1, p2);
+ return_type const d_crs1 = crs_AD - crs_AB;
+ return_type const sin_d_crs1 = sin(d_crs1);
+
+ // this constant sin() is here to be consistent with the side strategy
+ return_type const sigXTD = asin(sin(0.001) * sin_d_crs1);
+
+ // If the point is on the right side of the edge
+ if ( sigXTD > 0 )
+ {
+ return_type const crs_BA = crs_AB - geometry::math::pi<return_type>();
+ return_type const crs_BD = geometry::detail::course<return_type>(p2, point);
+ return_type const d_crs2 = crs_BD - crs_BA;
+
+ return_type const projection1 = cos( d_crs1 );
+ return_type const projection2 = cos( d_crs2 );
+
+ if(projection1 > 0.0 && projection2 > 0.0)
+ {
+ return_type const d1 = m_pp_strategy.apply(p1, point);
+ return_type const
+ XTD = radius()
+ * geometry::math::abs(
+ asin( sin( d1 / radius() ) * sin_d_crs1 )
+ );
+
+ return return_type(XTD);
+ }
+ else
+ {
+ // OPTIMIZATION
+ // Return d1 if projection1 <= 0 and d2 if projection2 <= 0
+ // if both == 0 then return d1 or d2
+ // both shouldn't be < 0
+
+ return_type const d1 = m_pp_strategy.apply(p1, point);
+ return_type const d2 = m_pp_strategy.apply(p2, point);
+
+ return return_type((std::min)( d1 , d2 ));
+ }
+ }
+ }
+
+ // Return 0 if the point isn't on the right side of any segment
+ return return_type(0);
+ }
+
+ inline typename Strategy::radius_type radius() const
+ { return m_pp_strategy.radius(); }
+
+private :
+
+ Strategy m_pp_strategy;
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename CalculationType, typename Strategy>
+struct tag<cross_track_point_box<CalculationType, Strategy> >
+{
+ typedef strategy_tag_distance_point_box type;
+};
+
+
+template <typename CalculationType, typename Strategy, typename P, typename Box>
+struct return_type<cross_track_point_box<CalculationType, Strategy>, P, Box>
+ : cross_track_point_box<CalculationType, Strategy>::template return_type<P, Box>
+{};
+
+
+template <typename CalculationType, typename Strategy>
+struct comparable_type<cross_track_point_box<CalculationType, Strategy> >
+{
+ // There is no shortcut, so the strategy itself is its comparable type
+ typedef cross_track_point_box<CalculationType, Strategy> type;
+};
+
+
+template
+<
+ typename CalculationType,
+ typename Strategy
+>
+struct get_comparable<cross_track_point_box<CalculationType, Strategy> >
+{
+ typedef typename comparable_type
+ <
+ cross_track_point_box<CalculationType, Strategy>
+ >::type comparable_type;
+public :
+ static inline comparable_type apply(
+ cross_track_point_box<CalculationType, Strategy> const& strategy)
+ {
+ return cross_track_point_box<CalculationType, Strategy>(strategy.radius());
+ }
+};
+
+
+template
+<
+ typename CalculationType,
+ typename Strategy,
+ typename P, typename Box
+>
+struct result_from_distance
+ <
+ cross_track_point_box<CalculationType, Strategy>,
+ P,
+ Box
+ >
+{
+private :
+ typedef typename cross_track_point_box
+ <
+ CalculationType, Strategy
+ >::template return_type<P, Box> return_type;
+public :
+ template <typename T>
+ static inline return_type apply(
+ cross_track_point_box<CalculationType, Strategy> const& ,
+ T const& distance)
+ {
+ return distance;
+ }
+};
+
+
+template <typename Point, typename Box, typename Strategy>
+struct default_strategy
+ <
+ point_tag, box_tag, Point, Box,
+ spherical_equatorial_tag, spherical_equatorial_tag,
+ Strategy
+ >
+{
+ typedef cross_track_point_box
+ <
+ void,
+ typename boost::mpl::if_
+ <
+ boost::is_void<Strategy>,
+ typename default_strategy
+ <
+ point_tag, point_tag,
+ Point, typename point_type<Box>::type,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ >::type,
+ Strategy
+ >::type
+ > type;
+};
+
+
+template <typename Box, typename Point, typename Strategy>
+struct default_strategy
+ <
+ box_tag, point_tag, Box, Point,
+ spherical_equatorial_tag, spherical_equatorial_tag,
+ Strategy
+ >
+{
+ typedef typename default_strategy
+ <
+ point_tag, box_tag, Point, Box,
+ spherical_equatorial_tag, spherical_equatorial_tag,
+ Strategy
+ >::type type;
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_POINT_BOX_HPP
diff --git a/3party/boost/boost/geometry/strategies/spherical/distance_haversine.hpp b/3party/boost/boost/geometry/strategies/spherical/distance_haversine.hpp
index 8db29c5157..8b32056f3e 100644
--- a/3party/boost/boost/geometry/strategies/spherical/distance_haversine.hpp
+++ b/3party/boost/boost/geometry/strategies/spherical/distance_haversine.hpp
@@ -158,7 +158,7 @@ public :
typedef typename calculation_type<Point1, Point2>::type calculation_type;
calculation_type const a = comparable_type::apply(p1, p2);
calculation_type const c = calculation_type(2.0) * asin(math::sqrt(a));
- return m_radius * c;
+ return calculation_type(m_radius) * c;
}
/*!
diff --git a/3party/boost/boost/geometry/strategies/spherical/side_by_cross_track.hpp b/3party/boost/boost/geometry/strategies/spherical/side_by_cross_track.hpp
index 818bd4c346..3f7be05557 100644
--- a/3party/boost/boost/geometry/strategies/spherical/side_by_cross_track.hpp
+++ b/3party/boost/boost/geometry/strategies/spherical/side_by_cross_track.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -9,16 +14,15 @@
#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/core/ignore_unused.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/algorithms/detail/course.hpp>
+
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategies/side.hpp>
//#include <boost/geometry/strategies/concepts/side_concept.hpp>
@@ -31,29 +35,6 @@ 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)
@@ -68,27 +49,19 @@ 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
+ typedef typename promote_floating_point
<
- boost::is_void<CalculationType>::type::value,
- typename select_most_precise
+ typename select_calculation_type_alt
<
- 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;
-
- boost::ignore_unused<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));
+ CalculationType,
+ P1, P2, P
+ >::type
+ >::type calc_t;
+
+ calc_t d1 = 0.001; // m_strategy.apply(sp1, p);
+ calc_t crs_AD = geometry::detail::course<calc_t>(p1, p);
+ calc_t crs_AB = geometry::detail::course<calc_t>(p1, p2);
+ calc_t XTD = asin(sin(d1) * sin(crs_AD - crs_AB));
return math::equals(XTD, 0) ? 0 : XTD < 0 ? 1 : -1;
}
diff --git a/3party/boost/boost/geometry/strategies/spherical/ssf.hpp b/3party/boost/boost/geometry/strategies/spherical/ssf.hpp
index 41562950fd..81f3205e90 100644
--- a/3party/boost/boost/geometry/strategies/spherical/ssf.hpp
+++ b/3party/boost/boost/geometry/strategies/spherical/ssf.hpp
@@ -16,8 +16,9 @@
#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/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategies/side.hpp>
//#include <boost/geometry/strategies/concepts/side_concept.hpp>
@@ -30,6 +31,43 @@ namespace boost { namespace geometry
namespace strategy { namespace side
{
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename T>
+int spherical_side_formula(T const& lambda1, T const& delta1,
+ T const& lambda2, T const& delta2,
+ T const& lambda, T const& delta)
+{
+ // Create temporary points (vectors) on unit a sphere
+ T const cos_delta1 = cos(delta1);
+ T const c1x = cos_delta1 * cos(lambda1);
+ T const c1y = cos_delta1 * sin(lambda1);
+ T const c1z = sin(delta1);
+
+ T const cos_delta2 = cos(delta2);
+ T const c2x = cos_delta2 * cos(lambda2);
+ T const c2y = cos_delta2 * sin(lambda2);
+ T const c2z = sin(delta2);
+
+ // (Third point is converted directly)
+ T const cos_delta = cos(delta);
+
+ // Apply the "Spherical Side Formula" as presented on my blog
+ T const dist
+ = (c1y * c2z - c1z * c2y) * cos_delta * cos(lambda)
+ + (c1z * c2x - c1x * c2z) * cos_delta * sin(lambda)
+ + (c1x * c2y - c1y * c2x) * sin(delta);
+
+ T zero = T();
+ return dist > zero ? 1
+ : dist < zero ? -1
+ : 0;
+}
+
+}
+#endif // DOXYGEN_NO_DETAIL
/*!
\brief Check at which side of a Great Circle segment a point lies
@@ -45,60 +83,25 @@ 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
+ typedef typename promote_floating_point
<
- boost::is_void<CalculationType>::type::value,
-
- // Select at least a double...
- typename select_most_precise
+ typename select_calculation_type_alt
<
- 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;
+ CalculationType,
+ P1, P2, P
+ >::type
+ >::type calculation_type;
+
+ calculation_type const lambda1 = get_as_radian<0>(p1);
+ calculation_type const delta1 = get_as_radian<1>(p1);
+ calculation_type const lambda2 = get_as_radian<0>(p2);
+ calculation_type const delta2 = get_as_radian<1>(p2);
+ calculation_type const lambda = get_as_radian<0>(p);
+ calculation_type const delta = get_as_radian<1>(p);
+
+ return detail::spherical_side_formula(lambda1, delta1,
+ lambda2, delta2,
+ lambda, delta);
}
};
diff --git a/3party/boost/boost/geometry/strategies/strategies.hpp b/3party/boost/boost/geometry/strategies/strategies.hpp
index 5e70e8a02c..28850020af 100644
--- a/3party/boost/boost/geometry/strategies/strategies.hpp
+++ b/3party/boost/boost/geometry/strategies/strategies.hpp
@@ -4,8 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -14,8 +16,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_STRATEGIES_STRATEGIES_HPP
#define BOOST_GEOMETRY_STRATEGIES_STRATEGIES_HPP
@@ -55,14 +55,21 @@
#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/cartesian/distance_comparable_to_regular.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/distance_cross_track_point_box.hpp>
#include <boost/geometry/strategies/spherical/compare_circular.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
+#include <boost/geometry/strategies/geographic/distance_andoyer.hpp>
+#include <boost/geometry/strategies/geographic/distance_thomas.hpp>
+#include <boost/geometry/strategies/geographic/distance_vincenty.hpp>
+//#include <boost/geometry/strategies/geographic/side_andoyer.hpp>
+//#include <boost/geometry/strategies/geographic/side_thomas.hpp>
+//#include <boost/geometry/strategies/geographic/side_vincenty.hpp>
+
#include <boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp>
#include <boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp>
#include <boost/geometry/strategies/agnostic/hull_graham_andrew.hpp>
diff --git a/3party/boost/boost/geometry/strategies/strategy_transform.hpp b/3party/boost/boost/geometry/strategies/strategy_transform.hpp
index 9d3b1d910c..99fcb720c6 100644
--- a/3party/boost/boost/geometry/strategies/strategy_transform.hpp
+++ b/3party/boost/boost/geometry/strategies/strategy_transform.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -28,6 +33,7 @@
#include <boost/geometry/strategies/transform.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
namespace boost { namespace geometry
@@ -130,7 +136,15 @@ struct degree_radian_vv
assert_dimension<P1, 2>();
assert_dimension<P2, 2>();
- detail::transform_coordinates<P1, P2, 0, 2, F>::transform(p1, p2, math::d2r);
+ typedef typename promote_floating_point
+ <
+ typename select_coordinate_type<P1, P2>::type
+ >::type calculation_type;
+
+ detail::transform_coordinates
+ <
+ P1, P2, 0, 2, F
+ >::transform(p1, p2, math::d2r<calculation_type>());
return true;
}
};
@@ -143,7 +157,16 @@ struct degree_radian_vv_3
assert_dimension<P1, 3>();
assert_dimension<P2, 3>();
- detail::transform_coordinates<P1, P2, 0, 2, F>::transform(p1, p2, math::d2r);
+ typedef typename promote_floating_point
+ <
+ typename select_coordinate_type<P1, P2>::type
+ >::type calculation_type;
+
+ detail::transform_coordinates
+ <
+ P1, P2, 0, 2, F
+ >::transform(p1, p2, math::d2r<calculation_type>());
+
// Copy height or other third dimension
set<2>(p2, get<2>(p1));
return true;
diff --git a/3party/boost/boost/geometry/strategies/transform/matrix_transformers.hpp b/3party/boost/boost/geometry/strategies/transform/matrix_transformers.hpp
index 27a3a2ae80..699b91b3aa 100644
--- a/3party/boost/boost/geometry/strategies/transform/matrix_transformers.hpp
+++ b/3party/boost/boost/geometry/strategies/transform/matrix_transformers.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -40,6 +45,7 @@
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
@@ -340,7 +346,8 @@ struct as_radian<degree>
template <typename T>
static inline T get(T const& value)
{
- return value * math::d2r;
+ typedef typename promote_floating_point<T>::type promoted_type;
+ return value * math::d2r<promoted_type>();
}
};
diff --git a/3party/boost/boost/geometry/util/bare_type.hpp b/3party/boost/boost/geometry/util/bare_type.hpp
index 1b49de6436..26dd94a8ae 100644
--- a/3party/boost/boost/geometry/util/bare_type.hpp
+++ b/3party/boost/boost/geometry/util/bare_type.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2012 Bruno Lalande, Paris, France.
// Copyright (c) 2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,7 +16,10 @@
#ifndef BOOST_GEOMETRY_UTIL_BARE_TYPE_HPP
#define BOOST_GEOMETRY_UTIL_BARE_TYPE_HPP
-#include <boost/type_traits.hpp>
+
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/remove_reference.hpp>
namespace boost { namespace geometry
@@ -25,7 +33,13 @@ struct bare_type
{
typedef typename boost::remove_const
<
- typename boost::remove_pointer<T>::type
+ typename boost::remove_pointer
+ <
+ typename boost::remove_reference
+ <
+ T
+ >::type
+ >::type
>::type type;
};
diff --git a/3party/boost/boost/geometry/util/combine_if.hpp b/3party/boost/boost/geometry/util/combine_if.hpp
index 6d8d932a1c..cfc3449267 100644
--- a/3party/boost/boost/geometry/util/combine_if.hpp
+++ b/3party/boost/boost/geometry/util/combine_if.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
+// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -36,16 +41,16 @@ namespace util
\ingroup utility
\par Example
\code
- typedef mpl::vector<mpl::int_<0>, mpl::int_<1> > types;
+ typedef boost::mpl::vector<boost::mpl::int_<0>, boost::mpl::int_<1> > types;
typedef combine_if<types, types, always<true_> >::type combinations;
- typedef mpl::vector<
- pair<mpl::int_<1>, mpl::int_<1> >,
- pair<mpl::int_<1>, mpl::int_<0> >,
- pair<mpl::int_<0>, mpl::int_<1> >,
- pair<mpl::int_<0>, mpl::int_<0> >
+ typedef boost::mpl::vector<
+ pair<boost::mpl::int_<1>, boost::mpl::int_<1> >,
+ pair<boost::mpl::int_<1>, boost::mpl::int_<0> >,
+ pair<boost::mpl::int_<0>, boost::mpl::int_<1> >,
+ pair<boost::mpl::int_<0>, boost::mpl::int_<0> >
> result_types;
- BOOST_MPL_ASSERT(( mpl::equal<combinations, result_types> ));
+ BOOST_MPL_ASSERT(( boost::mpl::equal<combinations, result_types> ));
\endcode
*/
template <typename Sequence1, typename Sequence2, typename Pred>
@@ -56,18 +61,29 @@ struct combine_if
template <typename Result, typename T>
struct apply
{
- typedef typename mpl::fold<Sequence2, Result,
- mpl::if_
+ typedef typename boost::mpl::fold<Sequence2, Result,
+ boost::mpl::if_
<
- mpl::bind<typename mpl::lambda<Pred>::type, T, mpl::_2>,
- mpl::insert<mpl::_1, mpl::pair<T, mpl::_2> >,
- mpl::_1
+ boost::mpl::bind
+ <
+ typename boost::mpl::lambda<Pred>::type,
+ T,
+ boost::mpl::_2
+ >,
+ boost::mpl::insert
+ <
+ boost::mpl::_1, boost::mpl::pair<T, boost::mpl::_2>
+ >,
+ boost::mpl::_1
>
>::type type;
};
};
- typedef typename mpl::fold<Sequence1, mpl::set0<>, combine>::type type;
+ typedef typename boost::mpl::fold
+ <
+ Sequence1, boost::mpl::set0<>, combine
+ >::type type;
};
diff --git a/3party/boost/boost/geometry/util/compress_variant.hpp b/3party/boost/boost/geometry/util/compress_variant.hpp
index a94cf28894..363385965d 100644
--- a/3party/boost/boost/geometry/util/compress_variant.hpp
+++ b/3party/boost/boost/geometry/util/compress_variant.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -36,28 +41,31 @@ namespace detail
template <typename Variant>
struct unique_types:
- mpl::fold<
- typename mpl::reverse_fold<
+ boost::mpl::fold<
+ typename boost::mpl::reverse_fold<
typename Variant::types,
- mpl::set<>,
- mpl::insert<
- mpl::placeholders::_1,
- mpl::placeholders::_2
+ boost::mpl::set<>,
+ boost::mpl::insert<
+ boost::mpl::placeholders::_1,
+ boost::mpl::placeholders::_2
>
>::type,
- mpl::vector<>,
- mpl::push_back<mpl::placeholders::_1, mpl::placeholders::_2>
+ boost::mpl::vector<>,
+ boost::mpl::push_back
+ <
+ boost::mpl::placeholders::_1, boost::mpl::placeholders::_2
+ >
>
{};
template <typename Types>
struct variant_or_single:
- mpl::if_<
- mpl::equal_to<
- mpl::size<Types>,
- mpl::int_<1>
+ boost::mpl::if_<
+ boost::mpl::equal_to<
+ boost::mpl::size<Types>,
+ boost::mpl::int_<1>
>,
- typename mpl::front<Types>::type,
+ typename boost::mpl::front<Types>::type,
typename make_variant_over<Types>::type
>
{};
@@ -75,8 +83,8 @@ struct variant_or_single:
\code
typedef variant<int, float, int, long> variant_type;
typedef compress_variant<variant_type>::type compressed;
- typedef mpl::vector<int, float, long> result_types;
- BOOST_MPL_ASSERT(( mpl::equal<compressed::types, result_types> ));
+ typedef boost::mpl::vector<int, float, long> result_types;
+ BOOST_MPL_ASSERT(( boost::mpl::equal<compressed::types, result_types> ));
typedef variant<int, int, int> one_type_variant_type;
typedef compress_variant<one_type_variant_type>::type single_type;
diff --git a/3party/boost/boost/geometry/util/condition.hpp b/3party/boost/boost/geometry/util/condition.hpp
new file mode 100644
index 0000000000..aea4ad3ad1
--- /dev/null
+++ b/3party/boost/boost/geometry/util/condition.hpp
@@ -0,0 +1,44 @@
+// Boost.Geometry
+
+// Copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_CONDITION_HPP
+#define BOOST_GEOMETRY_UTIL_CONDITION_HPP
+
+
+#include <boost/config.hpp>
+
+
+// The macro defined in this file allows to suppress the MSVC
+// compiler warning C4127: conditional expression is constant
+
+#ifdef BOOST_MSVC
+
+// NOTE: The code commented out below contains an alternative implementation
+// of a macro using a free function. It was left here in case if in the future
+// version of MSVC for the code currently used in the macro implementation
+// the warning was generated.
+
+//#ifndef DOXYGEN_NO_DETAIL
+//namespace boost { namespace geometry { namespace detail {
+//BOOST_FORCEINLINE bool condition(bool const b) { return b; }
+//}}} // boost::geometry::detail
+//#endif // DOXYGEN_NO_DETAIL
+//#define BOOST_GEOMETRY_CONDITION(CONDITION) boost::geometry::detail::condition(CONDITION)
+
+#define BOOST_GEOMETRY_CONDITION(CONDITION) ((void)0, (CONDITION))
+
+#else
+
+#define BOOST_GEOMETRY_CONDITION(CONDITION) (CONDITION)
+
+#endif
+
+
+#endif // BOOST_GEOMETRY_UTIL_CONDITION_HPP
diff --git a/3party/boost/boost/geometry/util/math.hpp b/3party/boost/boost/geometry/util/math.hpp
index 89f4578c07..4adc6a4edd 100644
--- a/3party/boost/boost/geometry/util/math.hpp
+++ b/3party/boost/boost/geometry/util/math.hpp
@@ -1,13 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -22,10 +23,14 @@
#include <cmath>
#include <limits>
-#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <boost/math/constants/constants.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/math/special_functions/round.hpp>
#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/type_traits/is_integral.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
@@ -39,11 +44,104 @@ namespace math
namespace detail
{
+template <typename T>
+inline T const& greatest(T const& v1, T const& v2)
+{
+ return (std::max)(v1, v2);
+}
+
+template <typename T>
+inline T const& greatest(T const& v1, T const& v2, T const& v3)
+{
+ return (std::max)(greatest(v1, v2), v3);
+}
+
+template <typename T>
+inline T const& greatest(T const& v1, T const& v2, T const& v3, T const& v4)
+{
+ return (std::max)(greatest(v1, v2, v3), v4);
+}
+
+template <typename T>
+inline T const& greatest(T const& v1, T const& v2, T const& v3, T const& v4, T const& v5)
+{
+ return (std::max)(greatest(v1, v2, v3, v4), v5);
+}
+
-template <typename Type, bool IsFloatingPoint>
+template <typename T,
+ bool IsFloatingPoint = boost::is_floating_point<T>::value>
+struct abs
+{
+ static inline T apply(T const& value)
+ {
+ T const zero = T();
+ return value < zero ? -value : value;
+ }
+};
+
+template <typename T>
+struct abs<T, true>
+{
+ static inline T apply(T const& value)
+ {
+ return fabs(value);
+ }
+};
+
+
+struct equals_default_policy
+{
+ template <typename T>
+ static inline T apply(T const& a, T const& b)
+ {
+ // See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17
+ return greatest(abs<T>::apply(a), abs<T>::apply(b), T(1));
+ }
+};
+
+template <typename T,
+ bool IsFloatingPoint = boost::is_floating_point<T>::value>
+struct equals_factor_policy
+{
+ equals_factor_policy()
+ : factor(1) {}
+ explicit equals_factor_policy(T const& v)
+ : factor(greatest(abs<T>::apply(v), T(1)))
+ {}
+ equals_factor_policy(T const& v0, T const& v1, T const& v2, T const& v3)
+ : factor(greatest(abs<T>::apply(v0), abs<T>::apply(v1),
+ abs<T>::apply(v2), abs<T>::apply(v3),
+ T(1)))
+ {}
+
+ T const& apply(T const&, T const&) const
+ {
+ return factor;
+ }
+
+ T factor;
+};
+
+template <typename T>
+struct equals_factor_policy<T, false>
+{
+ equals_factor_policy() {}
+ explicit equals_factor_policy(T const&) {}
+ equals_factor_policy(T const& , T const& , T const& , T const& ) {}
+
+ static inline T apply(T const&, T const&)
+ {
+ return T(1);
+ }
+};
+
+template <typename Type,
+ bool IsFloatingPoint = boost::is_floating_point<Type>::value>
struct equals
{
- static inline bool apply(Type const& a, Type const& b)
+ template <typename Policy>
+ static inline bool apply(Type const& a, Type const& b, Policy const&)
{
return a == b;
}
@@ -52,25 +150,41 @@ struct equals
template <typename Type>
struct equals<Type, true>
{
- static inline Type get_max(Type const& a, Type const& b, Type const& c)
+ template <typename Policy>
+ static inline bool apply(Type const& a, Type const& b, Policy const& policy)
{
- return (std::max)((std::max)(a, b), c);
- }
+ boost::ignore_unused(policy);
- 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);
+ if (boost::math::isfinite(a) && boost::math::isfinite(b))
+ {
+ // If a is INF and b is e.g. 0, the expression below returns true
+ // but the values are obviously not equal, hence the condition
+ return abs<Type>::apply(a - b)
+ <= std::numeric_limits<Type>::epsilon() * policy.apply(a, b);
+ }
+ else
+ {
+ return a == b;
+ }
}
};
-template <typename Type, bool IsFloatingPoint>
+template <typename T1, typename T2, typename Policy>
+inline bool equals_by_policy(T1 const& a, T2 const& b, Policy const& policy)
+{
+ return detail::equals
+ <
+ typename select_most_precise<T1, T2>::type
+ >::apply(a, b, policy);
+}
+
+template <typename Type,
+ bool IsFloatingPoint = boost::is_floating_point<Type>::value>
struct smaller
{
static inline bool apply(Type const& a, Type const& b)
@@ -84,7 +198,7 @@ struct smaller<Type, true>
{
static inline bool apply(Type const& a, Type const& b)
{
- if (equals<Type, true>::apply(a, b))
+ if (equals<Type, true>::apply(a, b, equals_default_policy()))
{
return false;
}
@@ -93,8 +207,11 @@ struct smaller<Type, true>
};
-template <typename Type, bool IsFloatingPoint>
-struct equals_with_epsilon : public equals<Type, IsFloatingPoint> {};
+template <typename Type,
+ bool IsFloatingPoint = boost::is_floating_point<Type>::value>
+struct equals_with_epsilon
+ : public equals<Type, IsFloatingPoint>
+{};
template
<
@@ -119,28 +236,52 @@ struct square_root
}
};
-template <>
-struct square_root<float, true>
+template <typename FundamentalFP>
+struct square_root_for_fundamental_fp
{
- typedef float return_type;
+ typedef FundamentalFP return_type;
- static inline float apply(float const& value)
+ static inline FundamentalFP apply(FundamentalFP const& value)
{
- // for float use std::sqrt
+#ifdef BOOST_GEOMETRY_SQRT_CHECK_FINITENESS
+ // This is a workaround for some 32-bit platforms.
+ // For some of those platforms it has been reported that
+ // std::sqrt(nan) and/or std::sqrt(-nan) returns a finite value.
+ // For those platforms we need to define the macro
+ // BOOST_GEOMETRY_SQRT_CHECK_FINITENESS so that the argument
+ // to std::sqrt is checked appropriately before passed to std::sqrt
+ if (boost::math::isfinite(value))
+ {
+ return std::sqrt(value);
+ }
+ else if (boost::math::isinf(value) && value < 0)
+ {
+ return -std::numeric_limits<FundamentalFP>::quiet_NaN();
+ }
+ return value;
+#else
+ // for fundamental floating point numbers use std::sqrt
return std::sqrt(value);
+#endif // BOOST_GEOMETRY_SQRT_CHECK_FINITENESS
}
};
template <>
-struct square_root<long double, true>
+struct square_root<float, true>
+ : square_root_for_fundamental_fp<float>
{
- typedef long double return_type;
+};
- static inline long double apply(long double const& value)
- {
- // for long double use std::sqrt
- return std::sqrt(value);
- }
+template <>
+struct square_root<double, true>
+ : square_root_for_fundamental_fp<double>
+{
+};
+
+template <>
+struct square_root<long double, true>
+ : square_root_for_fundamental_fp<long double>
+{
};
template <typename T>
@@ -155,13 +296,74 @@ struct square_root<T, true>
// Note: in C++98 the only other possibility is double;
// in C++11 there are also overloads for integral types;
// this specialization works for those as well.
- return std::sqrt(boost::numeric_cast<double>(value));
+ return square_root_for_fundamental_fp
+ <
+ double
+ >::apply(boost::numeric_cast<double>(value));
+ }
+};
+
+
+
+template
+<
+ typename T,
+ bool IsFundemantal = boost::is_fundamental<T>::value /* false */
+>
+struct modulo
+{
+ typedef T return_type;
+
+ static inline T apply(T const& value1, T const& value2)
+ {
+ // for non-fundamental number types assume that a free
+ // function mod() is defined either:
+ // 1) at T's scope, or
+ // 2) at global scope
+ return mod(value1, value2);
}
};
+template
+<
+ typename Fundamental,
+ bool IsIntegral = boost::is_integral<Fundamental>::value
+>
+struct modulo_for_fundamental
+{
+ typedef Fundamental return_type;
+
+ static inline Fundamental apply(Fundamental const& value1,
+ Fundamental const& value2)
+ {
+ return value1 % value2;
+ }
+};
+
+// specialization for floating-point numbers
+template <typename Fundamental>
+struct modulo_for_fundamental<Fundamental, false>
+{
+ typedef Fundamental return_type;
+
+ static inline Fundamental apply(Fundamental const& value1,
+ Fundamental const& value2)
+ {
+ return std::fmod(value1, value2);
+ }
+};
+
+// specialization for fundamental number type
+template <typename Fundamental>
+struct modulo<Fundamental, true>
+ : modulo_for_fundamental<Fundamental>
+{};
+
+
/*!
-\brief Short construct to enable partial specialization for PI, currently not possible in Math.
+\brief Short constructs to enable partial specialization for PI, 2*PI
+ and PI/2, currently not possible in Math.
*/
template <typename T>
struct define_pi
@@ -174,6 +376,26 @@ struct define_pi
};
template <typename T>
+struct define_two_pi
+{
+ static inline T apply()
+ {
+ // Default calls Boost.Math
+ return boost::math::constants::two_pi<T>();
+ }
+};
+
+template <typename T>
+struct define_half_pi
+{
+ static inline T apply()
+ {
+ // Default calls Boost.Math
+ return boost::math::constants::half_pi<T>();
+ }
+};
+
+template <typename T>
struct relaxed_epsilon
{
static inline T apply(const T& factor)
@@ -200,9 +422,10 @@ struct round<Result, Source, true, false>
{
static inline Result apply(Source const& v)
{
- return v < 0
- ? boost::numeric_cast<Result>(ceil(v - 0.5f))
- : boost::numeric_cast<Result>(floor(v + 0.5f));
+ namespace bmp = boost::math::policies;
+ // ignore rounding errors for backward compatibility
+ typedef bmp::policy< bmp::rounding_error<bmp::ignore_error> > policy;
+ return boost::numeric_cast<Result>(boost::math::round(v, policy()));
}
};
@@ -214,6 +437,12 @@ template <typename T>
inline T pi() { return detail::define_pi<T>::apply(); }
template <typename T>
+inline T two_pi() { return detail::define_two_pi<T>::apply(); }
+
+template <typename T>
+inline T half_pi() { return detail::define_half_pi<T>::apply(); }
+
+template <typename T>
inline T relaxed_epsilon(T const& factor)
{
return detail::relaxed_epsilon<T>::apply(factor);
@@ -238,51 +467,54 @@ inline T relaxed_epsilon(T const& factor)
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);
+ typename select_most_precise<T1, T2>::type
+ >::apply(a, b, detail::equals_default_policy());
}
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);
+ typename select_most_precise<T1, T2>::type
+ >::apply(a, b, detail::equals_default_policy());
}
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
+ typename select_most_precise<T1, T2>::type
>::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
+ typename select_most_precise<T1, T2>::type
>::apply(b, a);
}
+template <typename T>
+inline T d2r()
+{
+ static T const conversion_coefficient = geometry::math::pi<T>() / T(180.0);
+ return conversion_coefficient;
+}
+
+template <typename T>
+inline T r2d()
+{
+ static T const conversion_coefficient = T(180.0) / geometry::math::pi<T>();
+ return conversion_coefficient;
+}
-double const d2r = geometry::math::pi<double>() / 180.0;
-double const r2d = 1.0 / d2r;
/*!
\brief Calculates the haversine of an angle
@@ -327,6 +559,24 @@ sqrt(T const& value)
}
/*!
+\brief Short utility to return the modulo of two values
+\ingroup utility
+\param value1 First value
+\param value2 Second value
+\return The result of the modulo operation on the (ordered) pair
+(value1, value2)
+*/
+template <typename T>
+inline typename detail::modulo<T>::return_type
+mod(T const& value1, T const& value2)
+{
+ return detail::modulo
+ <
+ T, boost::is_fundamental<T>::value
+ >::apply(value1, value2);
+}
+
+/*!
\brief Short utility to workaround gcc/clang problem that abs is converting to integer
and that older versions of MSVC does not support abs of long long...
\ingroup utility
@@ -334,8 +584,7 @@ sqrt(T const& value)
template<typename T>
inline T abs(T const& value)
{
- T const zero = T();
- return value < zero ? -value : value;
+ return detail::abs<T>::apply(value);
}
/*!
@@ -354,12 +603,11 @@ static inline int sign(T const& value)
\ingroup utility
\note If the source T is NOT an integral type and Result is an integral type
the value is rounded towards the closest integral value. Otherwise it's
- just casted.
+ casted.
*/
template <typename Result, typename T>
inline Result round(T const& v)
{
- // NOTE: boost::round() could be used instead but it throws in some situations
return detail::round<Result, T>::apply(v);
}
diff --git a/3party/boost/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp b/3party/boost/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp
new file mode 100644
index 0000000000..eb947bb092
--- /dev/null
+++ b/3party/boost/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp
@@ -0,0 +1,160 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
+#define BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace math
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename Units, typename CoordinateType>
+class normalize_spheroidal_box_coordinates
+{
+private:
+ typedef normalize_spheroidal_coordinates<Units, CoordinateType> normalize;
+ typedef constants_on_spheroid<CoordinateType, Units> constants;
+
+ static inline bool is_band(CoordinateType const& longitude1,
+ CoordinateType const& longitude2)
+ {
+ return ! math::smaller(math::abs(longitude1 - longitude2),
+ constants::period());
+ }
+
+public:
+ static inline void apply(CoordinateType& longitude1,
+ CoordinateType& latitude1,
+ CoordinateType& longitude2,
+ CoordinateType& latitude2,
+ bool band)
+ {
+ normalize::apply(longitude1, latitude1, false);
+ normalize::apply(longitude2, latitude2, false);
+
+ if (math::equals(latitude1, constants::min_latitude())
+ && math::equals(latitude2, constants::min_latitude()))
+ {
+ // box degenerates to the south pole
+ longitude1 = longitude2 = CoordinateType(0);
+ }
+ else if (math::equals(latitude1, constants::max_latitude())
+ && math::equals(latitude2, constants::max_latitude()))
+ {
+ // box degenerates to the north pole
+ longitude1 = longitude2 = CoordinateType(0);
+ }
+ else if (band)
+ {
+ // the box is a band between two small circles (parallel
+ // to the equator) on the spheroid
+ longitude1 = constants::min_longitude();
+ longitude2 = constants::max_longitude();
+ }
+ else if (longitude1 > longitude2)
+ {
+ // the box crosses the antimeridian, so we need to adjust
+ // the longitudes
+ longitude2 += constants::period();
+ }
+
+#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
+ BOOST_GEOMETRY_ASSERT(! math::larger(latitude1, latitude2));
+ BOOST_GEOMETRY_ASSERT(! math::smaller(latitude1, constants::min_latitude()));
+ BOOST_GEOMETRY_ASSERT(! math::larger(latitude2, constants::max_latitude()));
+#endif
+
+ BOOST_GEOMETRY_ASSERT(! math::larger(longitude1, longitude2));
+ BOOST_GEOMETRY_ASSERT(! math::smaller(longitude1, constants::min_longitude()));
+ BOOST_GEOMETRY_ASSERT
+ (! math::larger(longitude2 - longitude1, constants::period()));
+ }
+
+ static inline void apply(CoordinateType& longitude1,
+ CoordinateType& latitude1,
+ CoordinateType& longitude2,
+ CoordinateType& latitude2)
+ {
+ bool const band = is_band(longitude1, longitude2);
+
+ apply(longitude1, latitude1, longitude2, latitude2, band);
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Short utility to normalize the coordinates of a box on a spheroid
+\tparam Units The units of the coordindate system in the spheroid
+\tparam CoordinateType The type of the coordinates
+\param longitude1 Minimum longitude of the box
+\param latitude1 Minimum latitude of the box
+\param longitude2 Maximum longitude of the box
+\param latitude2 Maximum latitude of the box
+\ingroup utility
+*/
+template <typename Units, typename CoordinateType>
+inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
+ CoordinateType& latitude1,
+ CoordinateType& longitude2,
+ CoordinateType& latitude2)
+{
+ detail::normalize_spheroidal_box_coordinates
+ <
+ Units, CoordinateType
+ >::apply(longitude1, latitude1, longitude2, latitude2);
+}
+
+/*!
+\brief Short utility to normalize the coordinates of a box on a spheroid
+\tparam Units The units of the coordindate system in the spheroid
+\tparam CoordinateType The type of the coordinates
+\param longitude1 Minimum longitude of the box
+\param latitude1 Minimum latitude of the box
+\param longitude2 Maximum longitude of the box
+\param latitude2 Maximum latitude of the box
+\param band Indicates whether the box should be treated as a band or
+ not and avoid the computation done in the other version of the function
+\ingroup utility
+*/
+template <typename Units, typename CoordinateType>
+inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
+ CoordinateType& latitude1,
+ CoordinateType& longitude2,
+ CoordinateType& latitude2,
+ bool band)
+{
+ detail::normalize_spheroidal_box_coordinates
+ <
+ Units, CoordinateType
+ >::apply(longitude1, latitude1, longitude2, latitude2, band);
+}
+
+
+} // namespace math
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
diff --git a/3party/boost/boost/geometry/util/normalize_spheroidal_coordinates.hpp b/3party/boost/boost/geometry/util/normalize_spheroidal_coordinates.hpp
new file mode 100644
index 0000000000..72dfa5a6f1
--- /dev/null
+++ b/3party/boost/boost/geometry/util/normalize_spheroidal_coordinates.hpp
@@ -0,0 +1,218 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
+#define BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace math
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename CoordinateType, typename Units>
+struct constants_on_spheroid
+{
+ static inline CoordinateType period()
+ {
+ return math::two_pi<CoordinateType>();
+ }
+
+ static inline CoordinateType half_period()
+ {
+ return math::pi<CoordinateType>();
+ }
+
+ static inline CoordinateType min_longitude()
+ {
+ static CoordinateType const minus_pi = -math::pi<CoordinateType>();
+ return minus_pi;
+ }
+
+ static inline CoordinateType max_longitude()
+ {
+ return math::pi<CoordinateType>();
+ }
+
+ static inline CoordinateType min_latitude()
+ {
+ static CoordinateType const minus_half_pi
+ = -math::half_pi<CoordinateType>();
+ return minus_half_pi;
+ }
+
+ static inline CoordinateType max_latitude()
+ {
+ return math::half_pi<CoordinateType>();
+ }
+};
+
+template <typename CoordinateType>
+struct constants_on_spheroid<CoordinateType, degree>
+{
+ static inline CoordinateType period()
+ {
+ return CoordinateType(360.0);
+ }
+
+ static inline CoordinateType half_period()
+ {
+ return CoordinateType(180.0);
+ }
+
+ static inline CoordinateType min_longitude()
+ {
+ return CoordinateType(-180.0);
+ }
+
+ static inline CoordinateType max_longitude()
+ {
+ return CoordinateType(180.0);
+ }
+
+ static inline CoordinateType min_latitude()
+ {
+ return CoordinateType(-90.0);
+ }
+
+ static inline CoordinateType max_latitude()
+ {
+ return CoordinateType(90.0);
+ }
+};
+
+
+template <typename Units, typename CoordinateType>
+class normalize_spheroidal_coordinates
+{
+ typedef constants_on_spheroid<CoordinateType, Units> constants;
+
+protected:
+ static inline CoordinateType normalize_up(CoordinateType const& value)
+ {
+ return
+ math::mod(value + constants::half_period(), constants::period())
+ - constants::half_period();
+ }
+
+ static inline CoordinateType normalize_down(CoordinateType const& value)
+ {
+ return
+ math::mod(value - constants::half_period(), constants::period())
+ + constants::half_period();
+ }
+
+public:
+ static inline void apply(CoordinateType& longitude,
+ CoordinateType& latitude,
+ bool normalize_poles = true)
+ {
+#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
+ // normalize latitude
+ if (math::larger(latitude, constants::half_period()))
+ {
+ latitude = normalize_up(latitude);
+ }
+ else if (math::smaller(latitude, -constants::half_period()))
+ {
+ latitude = normalize_down(latitude);
+ }
+
+ // fix latitude range
+ if (latitude < constants::min_latitude())
+ {
+ latitude = -constants::half_period() - latitude;
+ longitude -= constants::half_period();
+ }
+ else if (latitude > constants::max_latitude())
+ {
+ latitude = constants::half_period() - latitude;
+ longitude -= constants::half_period();
+ }
+#endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE
+
+ // normalize longitude
+ if (math::equals(math::abs(longitude), constants::half_period()))
+ {
+ longitude = constants::half_period();
+ }
+ else if (longitude > constants::half_period())
+ {
+ longitude = normalize_up(longitude);
+ if (math::equals(longitude, -constants::half_period()))
+ {
+ longitude = constants::half_period();
+ }
+ }
+ else if (longitude < -constants::half_period())
+ {
+ longitude = normalize_down(longitude);
+ }
+
+ // finally normalize poles
+ if (normalize_poles)
+ {
+ if (math::equals(math::abs(latitude), constants::max_latitude()))
+ {
+ // for the north and south pole we set the longitude to 0
+ // (works for both radians and degrees)
+ longitude = CoordinateType(0);
+ }
+ }
+
+#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
+ BOOST_GEOMETRY_ASSERT(! math::larger(constants::min_latitude(), latitude));
+ BOOST_GEOMETRY_ASSERT(! math::larger(latitude, constants::max_latitude()));
+#endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE
+
+ BOOST_GEOMETRY_ASSERT(math::smaller(constants::min_longitude(), longitude));
+ BOOST_GEOMETRY_ASSERT(! math::larger(longitude, constants::max_longitude()));
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Short utility to normalize the coordinates on a spheroid
+\tparam Units The units of the coordindate system in the spheroid
+\tparam CoordinateType The type of the coordinates
+\param longitude Longitude
+\param latitude Latitude
+\ingroup utility
+*/
+template <typename Units, typename CoordinateType>
+inline void normalize_spheroidal_coordinates(CoordinateType& longitude,
+ CoordinateType& latitude)
+{
+ detail::normalize_spheroidal_coordinates
+ <
+ Units, CoordinateType
+ >::apply(longitude, latitude);
+}
+
+
+} // namespace math
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_COORDINATES_HPP
diff --git a/3party/boost/boost/geometry/util/promote_integral.hpp b/3party/boost/boost/geometry/util/promote_integral.hpp
new file mode 100644
index 0000000000..6b23403be3
--- /dev/null
+++ b/3party/boost/boost/geometry/util/promote_integral.hpp
@@ -0,0 +1,318 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
+#define BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
+
+// For now deactivate the use of multiprecision integers
+// TODO: activate it later
+#define BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER
+
+#include <climits>
+#include <cstddef>
+
+#include <boost/mpl/begin.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/mpl/size_t.hpp>
+
+#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
+#include <boost/multiprecision/cpp_int.hpp>
+#endif
+
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace promote_integral
+{
+
+// meta-function that returns the bit size of a type
+template
+<
+ typename T,
+ bool IsFundamental = boost::is_fundamental<T>::type::value
+>
+struct bit_size
+{};
+
+
+// for fundamental types, just return CHAR_BIT * sizeof(T)
+template <typename T>
+struct bit_size<T, true>
+ : boost::mpl::size_t<(CHAR_BIT * sizeof(T))>
+{};
+
+
+#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
+// partial specialization for cpp_int
+template
+<
+ unsigned MinSize,
+ unsigned MaxSize,
+ boost::multiprecision::cpp_integer_type SignType,
+ boost::multiprecision::cpp_int_check_type Checked,
+ typename Allocator,
+ boost::multiprecision::expression_template_option ExpressionTemplates
+>
+struct bit_size
+ <
+ boost::multiprecision::number
+ <
+ boost::multiprecision::cpp_int_backend
+ <
+ MinSize, MaxSize, SignType, Checked, Allocator
+ >,
+ ExpressionTemplates
+ >,
+ false
+ > : boost::mpl::size_t<MaxSize>
+{};
+#endif // BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER
+
+
+template
+<
+ typename T,
+ typename Iterator,
+ typename EndIterator,
+ std::size_t MinSize
+>
+struct promote_to_larger
+{
+ typedef typename boost::mpl::deref<Iterator>::type current_type;
+
+ typedef typename boost::mpl::if_c
+ <
+ (bit_size<current_type>::type::value >= MinSize),
+ current_type,
+ typename promote_to_larger
+ <
+ T,
+ typename boost::mpl::next<Iterator>::type,
+ EndIterator,
+ MinSize
+ >::type
+ >::type type;
+};
+
+// The following specialization is required to finish the loop over
+// all list elements
+template <typename T, typename EndIterator, std::size_t MinSize>
+struct promote_to_larger<T, EndIterator, EndIterator, MinSize>
+{
+ // if promotion fails, keep the number T
+ // (and cross fingers that overflow will not occur)
+ typedef T type;
+};
+
+}} // namespace detail::promote_integral
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+/*!
+ \brief Meta-function to define an integral type with size
+ than is (roughly) twice the bit size of T
+ \ingroup utility
+ \details
+ This meta-function tries to promote the fundamental integral type T
+ to a another integral type with size (roughly) twice the bit size of T.
+
+ To do this, two times the bit size of T is tested against the bit sizes of:
+ short, int, long, boost::long_long_type, boost::int128_t
+ and the one that first matches is chosen.
+
+ For unsigned types the bit size of T is tested against the bit
+ sizes of the types above, if T is promoted to a signed type, or
+ the bit sizes of
+ unsigned short, unsigned int, unsigned long, std::size_t,
+ boost::ulong_long_type, boost::uint128_t
+ if T is promoted to an unsigned type.
+
+ By default an unsigned type is promoted to a signed type.
+ This behavior is controlled by the PromoteUnsignedToUnsigned
+ boolean template parameter, whose default value is "false".
+ To promote an unsigned type to an unsigned type set the value of
+ this template parameter to "true".
+
+ If the macro BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER is not
+ defined, boost's multiprecision integer cpp_int<> is used as a
+ last resort.
+
+ If BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER is defined and an
+ appropriate type cannot be detected, the input type is returned as is.
+
+ Finally, if the passed type is either a floating-point type or a
+ user-defined type it is returned as is.
+
+ \note boost::long_long_type and boost::ulong_long_type are
+ considered only if the macro BOOST_HAS_LONG_LONG is defined
+
+ \note boost::int128_type and boost::uint128_type are considered
+ only if the macros BOOST_HAS_INT128 and BOOST_GEOMETRY_ENABLE_INT128
+ are defined
+*/
+template
+<
+ typename T,
+ bool PromoteUnsignedToUnsigned = false,
+ bool UseCheckedInteger = false,
+ bool IsIntegral = boost::is_integral<T>::type::value
+>
+class promote_integral
+{
+private:
+ static bool const is_unsigned = boost::is_unsigned<T>::type::value;
+
+ typedef detail::promote_integral::bit_size<T> bit_size_type;
+
+#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
+ // Define the proper check policy for the multiprecision integer
+ typedef typename boost::mpl::if_c
+ <
+ UseCheckedInteger,
+ boost::integral_constant
+ <
+ boost::multiprecision::cpp_int_check_type,
+ boost::multiprecision::checked
+ >,
+ boost::integral_constant
+ <
+ boost::multiprecision::cpp_int_check_type,
+ boost::multiprecision::unchecked
+ >
+ >::type check_policy_type;
+
+ // Meta-function to get the multiprecision integer type for the
+ // given size and sign type (signed/unsigned)
+ template
+ <
+ unsigned int Size,
+ boost::multiprecision::cpp_integer_type SignType
+ >
+ struct multiprecision_integer_type
+ {
+ typedef boost::multiprecision::number
+ <
+ boost::multiprecision::cpp_int_backend
+ <
+ Size,
+ Size,
+ SignType,
+ check_policy_type::value,
+ void
+ >
+ > type;
+ };
+#endif
+
+ // Define the minimum size (in bits) needed for the promoted type
+ // If T is the input type and P the promoted type, then the
+ // minimum number of bits for P are (below b stands for the number
+ // of bits of T):
+ // * if T is unsigned and P is unsigned: 2 * b
+ // * if T is signed and P is signed: 2 * b - 1
+ // * if T is unsigned and P is signed: 2 * b + 1
+ typedef typename boost::mpl::if_c
+ <
+ (PromoteUnsignedToUnsigned && is_unsigned),
+ boost::mpl::size_t<(2 * bit_size_type::value)>,
+ typename boost::mpl::if_c
+ <
+ is_unsigned,
+ boost::mpl::size_t<(2 * bit_size_type::value + 1)>,
+ boost::mpl::size_t<(2 * bit_size_type::value - 1)>
+ >::type
+ >::type min_bit_size_type;
+
+ // Define the list of signed integral types we are going to use
+ // for promotion
+ typedef boost::mpl::list
+ <
+ short, int, long
+#if defined(BOOST_HAS_LONG_LONG)
+ , boost::long_long_type
+#endif
+#if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
+ , boost::int128_type
+#endif
+#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
+ , typename multiprecision_integer_type
+ <
+ min_bit_size_type::value,
+ boost::multiprecision::signed_magnitude
+ >::type
+#endif
+ > signed_integral_types;
+
+ // Define the list of unsigned integral types we are going to use
+ // for promotion
+ typedef boost::mpl::list
+ <
+ unsigned short, unsigned int, unsigned long, std::size_t
+#if defined(BOOST_HAS_LONG_LONG)
+ , boost::ulong_long_type
+#endif
+#if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128)
+ , boost::uint128_type
+#endif
+#if !defined(BOOST_GEOMETRY_NO_MULTIPRECISION_INTEGER)
+ , typename multiprecision_integer_type
+ <
+ min_bit_size_type::value,
+ boost::multiprecision::unsigned_magnitude
+ >::type
+#endif
+ > unsigned_integral_types;
+
+ // Define the list of integral types that will be used for
+ // promotion (depending in whether we was to promote unsigned to
+ // unsigned or not)
+ typedef typename boost::mpl::if_c
+ <
+ (is_unsigned && PromoteUnsignedToUnsigned),
+ unsigned_integral_types,
+ signed_integral_types
+ >::type integral_types;
+
+public:
+ typedef typename detail::promote_integral::promote_to_larger
+ <
+ T,
+ typename boost::mpl::begin<integral_types>::type,
+ typename boost::mpl::end<integral_types>::type,
+ min_bit_size_type::value
+ >::type type;
+};
+
+
+template <typename T, bool PromoteUnsignedToUnsigned, bool UseCheckedInteger>
+class promote_integral
+ <
+ T, PromoteUnsignedToUnsigned, UseCheckedInteger, false
+ >
+{
+public:
+ typedef T type;
+};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_UTIL_PROMOTE_INTEGRAL_HPP
diff --git a/3party/boost/boost/geometry/util/range.hpp b/3party/boost/boost/geometry/util/range.hpp
index fe3502f978..0f480df58a 100644
--- a/3party/boost/boost/geometry/util/range.hpp
+++ b/3party/boost/boost/geometry/util/range.hpp
@@ -2,21 +2,20 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015.
+// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_UTIL_RANGE_HPP
#define BOOST_GEOMETRY_UTIL_RANGE_HPP
#include <algorithm>
-#include <boost/assert.hpp>
#include <boost/concept_check.hpp>
#include <boost/config.hpp>
#include <boost/range/concepts.hpp>
@@ -26,24 +25,68 @@
#include <boost/range/size.hpp>
#include <boost/type_traits/is_convertible.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/mutable_range.hpp>
namespace boost { namespace geometry { namespace range {
-// NOTE: For SinglePassRanges at could iterate over all elements until the i-th element is met.
+namespace detail {
+
+// NOTE: For SinglePassRanges pos could iterate over all elements until the i-th element was met.
+
+template <typename RandomAccessRange>
+struct pos
+{
+ typedef typename boost::range_iterator<RandomAccessRange>::type iterator;
+ typedef typename boost::range_size<RandomAccessRange>::type size_type;
+ typedef typename boost::range_difference<RandomAccessRange>::type difference_type;
+
+ static inline iterator apply(RandomAccessRange & rng, size_type i)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<RandomAccessRange> ));
+ return boost::begin(rng) + static_cast<difference_type>(i);
+ }
+};
+
+} // namespace detail
+
+/*!
+\brief Short utility to conveniently return an iterator of a RandomAccessRange.
+\ingroup utility
+*/
+template <typename RandomAccessRange>
+inline typename boost::range_iterator<RandomAccessRange const>::type
+pos(RandomAccessRange const& rng,
+ typename boost::range_size<RandomAccessRange const>::type i)
+{
+ BOOST_GEOMETRY_ASSERT(i <= boost::size(rng));
+ return detail::pos<RandomAccessRange const>::apply(rng, i);
+}
+
+/*!
+\brief Short utility to conveniently return an iterator of a RandomAccessRange.
+\ingroup utility
+*/
+template <typename RandomAccessRange>
+inline typename boost::range_iterator<RandomAccessRange>::type
+pos(RandomAccessRange & rng,
+ typename boost::range_size<RandomAccessRange>::type i)
+{
+ BOOST_GEOMETRY_ASSERT(i <= boost::size(rng));
+ return detail::pos<RandomAccessRange>::apply(rng, i);
+}
/*!
\brief Short utility to conveniently return an element of a RandomAccessRange.
\ingroup utility
*/
template <typename RandomAccessRange>
-inline typename boost::range_value<RandomAccessRange const>::type const&
+inline typename boost::range_reference<RandomAccessRange const>::type
at(RandomAccessRange const& rng,
typename boost::range_size<RandomAccessRange const>::type i)
{
- BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<RandomAccessRange const> ));
- BOOST_ASSERT(i < boost::size(rng));
- return *(boost::begin(rng) + i);
+ BOOST_GEOMETRY_ASSERT(i < boost::size(rng));
+ return * detail::pos<RandomAccessRange const>::apply(rng, i);
}
/*!
@@ -51,13 +94,12 @@ at(RandomAccessRange const& rng,
\ingroup utility
*/
template <typename RandomAccessRange>
-inline typename boost::range_value<RandomAccessRange>::type &
+inline typename boost::range_reference<RandomAccessRange>::type
at(RandomAccessRange & rng,
typename boost::range_size<RandomAccessRange>::type i)
{
- BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<RandomAccessRange> ));
- BOOST_ASSERT(i < boost::size(rng));
- return *(boost::begin(rng) + i);
+ BOOST_GEOMETRY_ASSERT(i < boost::size(rng));
+ return * detail::pos<RandomAccessRange>::apply(rng, i);
}
/*!
@@ -65,10 +107,10 @@ at(RandomAccessRange & rng,
\ingroup utility
*/
template <typename Range>
-inline typename boost::range_value<Range>::type const&
+inline typename boost::range_reference<Range const>::type
front(Range const& rng)
{
- BOOST_ASSERT(!boost::empty(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *boost::begin(rng);
}
@@ -77,10 +119,10 @@ front(Range const& rng)
\ingroup utility
*/
template <typename Range>
-inline typename boost::range_value<Range>::type &
+inline typename boost::range_reference<Range>::type
front(Range & rng)
{
- BOOST_ASSERT(!boost::empty(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *boost::begin(rng);
}
@@ -91,12 +133,12 @@ front(Range & rng)
\ingroup utility
*/
template <typename BidirectionalRange>
-inline typename boost::range_value<BidirectionalRange>::type const&
+inline typename boost::range_reference<BidirectionalRange const>::type
back(BidirectionalRange const& rng)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRange const> ));
- BOOST_ASSERT(!boost::empty(rng));
- return *(--boost::end(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
+ return *(boost::rbegin(rng));
}
/*!
@@ -104,12 +146,12 @@ back(BidirectionalRange const& rng)
\ingroup utility
*/
template <typename BidirectionalRange>
-inline typename boost::range_value<BidirectionalRange>::type &
+inline typename boost::range_reference<BidirectionalRange>::type
back(BidirectionalRange & rng)
{
- BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRange> ));
- BOOST_ASSERT(!boost::empty(rng));
- return *(--boost::end(rng));
+ BOOST_RANGE_CONCEPT_ASSERT((boost::BidirectionalRangeConcept<BidirectionalRange>));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
+ return *(boost::rbegin(rng));
}
@@ -158,7 +200,7 @@ inline void resize(Range & rng,
template <typename Range>
inline void pop_back(Range & rng)
{
- BOOST_ASSERT(!boost::empty(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
range::resize(rng, boost::size(rng) - 1);
}
@@ -218,8 +260,8 @@ inline typename boost::range_iterator<Range>::type
erase(Range & rng,
typename boost::range_iterator<Range>::type it)
{
- BOOST_ASSERT(!boost::empty(rng));
- BOOST_ASSERT(it != boost::end(rng));
+ BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
+ BOOST_GEOMETRY_ASSERT(it != boost::end(rng));
typename boost::range_difference<Range>::type const
d = std::distance(boost::begin(rng), it);
@@ -272,10 +314,10 @@ erase(Range & rng,
{
typename boost::range_difference<Range>::type const
diff = std::distance(first, last);
- BOOST_ASSERT(diff >= 0);
+ BOOST_GEOMETRY_ASSERT(diff >= 0);
std::size_t const count = static_cast<std::size_t>(diff);
- BOOST_ASSERT(count <= boost::size(rng));
+ BOOST_GEOMETRY_ASSERT(count <= boost::size(rng));
if ( count > 0 )
{
diff --git a/3party/boost/boost/geometry/util/select_calculation_type.hpp b/3party/boost/boost/geometry/util/select_calculation_type.hpp
index 4946c45e84..0e3faf229b 100644
--- a/3party/boost/boost/geometry/util/select_calculation_type.hpp
+++ b/3party/boost/boost/geometry/util/select_calculation_type.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -50,6 +55,28 @@ struct select_calculation_type
>::type type;
};
+// alternative version supporting more than 2 Geometries
+
+template <typename CalculationType,
+ typename Geometry1,
+ typename Geometry2 = void,
+ typename Geometry3 = void>
+struct select_calculation_type_alt
+{
+ typedef typename
+ boost::mpl::if_
+ <
+ boost::is_void<CalculationType>,
+ typename select_coordinate_type
+ <
+ Geometry1,
+ Geometry2,
+ Geometry3
+ >::type,
+ CalculationType
+ >::type type;
+};
+
}} // namespace boost::geometry
diff --git a/3party/boost/boost/geometry/util/select_coordinate_type.hpp b/3party/boost/boost/geometry/util/select_coordinate_type.hpp
index 8309da42b7..12a6b72a73 100644
--- a/3party/boost/boost/geometry/util/select_coordinate_type.hpp
+++ b/3party/boost/boost/geometry/util/select_coordinate_type.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -28,16 +33,35 @@ namespace boost { namespace geometry
of two geometries
\ingroup utility
*/
-template <typename T1, typename T2>
+template <typename T1, typename T2 = void, typename T3 = void>
struct select_coordinate_type
{
typedef typename select_most_precise
<
typename coordinate_type<T1>::type,
+ typename coordinate_type<T2>::type,
+ typename coordinate_type<T3>::type
+ >::type type;
+};
+
+template <typename T1, typename T2>
+struct select_coordinate_type<T1, T2, void>
+{
+ typedef typename select_most_precise
+ <
+ typename coordinate_type<T1>::type,
typename coordinate_type<T2>::type
>::type type;
};
+template <typename T1>
+struct select_coordinate_type<T1, void, void>
+{
+ typedef typename select_most_precise
+ <
+ typename coordinate_type<T1>::type
+ >::type type;
+};
}} // namespace boost::geometry
diff --git a/3party/boost/boost/geometry/util/select_most_precise.hpp b/3party/boost/boost/geometry/util/select_most_precise.hpp
index d55fdbfd98..b5b1388cf8 100644
--- a/3party/boost/boost/geometry/util/select_most_precise.hpp
+++ b/3party/boost/boost/geometry/util/select_most_precise.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -113,9 +118,19 @@ struct select_floating_point<false, true, T1, T2>
\note If both types are non-fundamental, the result is indeterminate and
currently the first one is chosen.
*/
-template <typename T1, typename T2>
+template <typename T1, typename T2 = void, typename T3 = void>
struct select_most_precise
{
+ typedef typename select_most_precise
+ <
+ typename select_most_precise<T1, T2>::type,
+ T3
+ >::type type;
+};
+
+template <typename T1, typename T2>
+struct select_most_precise<T1, T2, void>
+{
static const bool second_larger = sizeof(T2) > sizeof(T1);
static const bool one_not_fundamental = !
(boost::is_fundamental<T1>::type::value
@@ -155,7 +170,11 @@ struct select_most_precise
>::type type;
};
-
+template <typename T1>
+struct select_most_precise<T1, void, void>
+{
+ typedef T1 type;
+};
}} // namespace boost::geometry
diff --git a/3party/boost/boost/geometry/util/transform_variant.hpp b/3party/boost/boost/geometry/util/transform_variant.hpp
index 9e4a7aa152..f0836bcbf2 100644
--- a/3party/boost/boost/geometry/util/transform_variant.hpp
+++ b/3party/boost/boost/geometry/util/transform_variant.hpp
@@ -1,8 +1,13 @@
// 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.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -31,7 +36,7 @@ namespace boost { namespace geometry
\ingroup utility
\par Example
\code
- typedef mpl::vector<int, float, long> types;
+ typedef boost::mpl::vector<int, float, long> types;
typedef transform_variant<types, add_pointer<_> > transformed;
typedef variant<int*, float*, long*> result;
BOOST_MPL_ASSERT(( equal<result, transformed> ));
@@ -40,7 +45,7 @@ namespace boost { namespace geometry
template <typename Sequence, typename Op, typename In = boost::mpl::na>
struct transform_variant:
make_variant_over<
- typename mpl::transform<
+ typename boost::mpl::transform<
Sequence,
Op,
In
@@ -65,7 +70,7 @@ struct transform_variant:
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Op>
struct transform_variant<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Op, boost::mpl::na> :
make_variant_over<
- typename mpl::transform<
+ typename boost::mpl::transform<
typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types,
Op
>::type
diff --git a/3party/boost/boost/geometry/views/box_view.hpp b/3party/boost/boost/geometry/views/box_view.hpp
index 3f448efe81..4ecb941ec9 100644
--- a/3party/boost/boost/geometry/views/box_view.hpp
+++ b/3party/boost/boost/geometry/views/box_view.hpp
@@ -68,7 +68,11 @@ private :
inline void apply(point_type* points) const
{
- detail::assign_box_corners_oriented<!Clockwise>(m_box, points);
+ // assign_box_corners_oriented requires a range
+ // an alternative for this workaround would be to pass a range here,
+ // e.g. use boost::array in points_view instead of c-array
+ std::pair<point_type*, point_type*> rng = std::make_pair(points, points + 5);
+ detail::assign_box_corners_oriented<!Clockwise>(m_box, rng);
points[4] = points[0];
}
private :
diff --git a/3party/boost/boost/geometry/views/detail/indexed_point_view.hpp b/3party/boost/boost/geometry/views/detail/indexed_point_view.hpp
index 88b13ec5c4..e5a89c9ae7 100644
--- a/3party/boost/boost/geometry/views/detail/indexed_point_view.hpp
+++ b/3party/boost/boost/geometry/views/detail/indexed_point_view.hpp
@@ -1,9 +1,14 @@
// 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.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -62,41 +67,47 @@ namespace traits
{
template <typename Geometry, std::size_t Index>
-struct tag< detail::indexed_point_view<Geometry, Index> >
+struct tag< geometry::detail::indexed_point_view<Geometry, Index> >
{
typedef point_tag type;
};
template <typename Geometry, std::size_t Index>
-struct coordinate_type< detail::indexed_point_view<Geometry, Index> >
+struct coordinate_type< geometry::detail::indexed_point_view<Geometry, Index> >
{
typedef typename geometry::coordinate_type<Geometry>::type type;
};
template <typename Geometry, std::size_t Index>
-struct coordinate_system< detail::indexed_point_view<Geometry, Index> >
+struct coordinate_system
+ <
+ geometry::detail::indexed_point_view<Geometry, Index>
+ >
{
typedef typename geometry::coordinate_system<Geometry>::type type;
};
template <typename Geometry, std::size_t Index>
-struct dimension< detail::indexed_point_view<Geometry, Index> >
+struct dimension< geometry::detail::indexed_point_view<Geometry, Index> >
: geometry::dimension<Geometry>
{};
template<typename Geometry, std::size_t Index, std::size_t Dimension>
-struct access< detail::indexed_point_view<Geometry, Index>, Dimension >
+struct access
+ <
+ geometry::detail::indexed_point_view<Geometry, Index>, Dimension
+ >
{
typedef typename geometry::coordinate_type<Geometry>::type coordinate_type;
static inline coordinate_type get(
- detail::indexed_point_view<Geometry, Index> const& p)
+ geometry::detail::indexed_point_view<Geometry, Index> const& p)
{
return p.template get<Dimension>();
}
static inline void set(
- detail::indexed_point_view<Geometry, Index> & p,
+ geometry::detail::indexed_point_view<Geometry, Index> & p,
coordinate_type const& value)
{
p.template set<Dimension>(value);
diff --git a/3party/boost/boost/geometry/views/detail/normalized_view.hpp b/3party/boost/boost/geometry/views/detail/normalized_view.hpp
index d50ffe48c8..1e9cda9ce2 100644
--- a/3party/boost/boost/geometry/views/detail/normalized_view.hpp
+++ b/3party/boost/boost/geometry/views/detail/normalized_view.hpp
@@ -28,6 +28,7 @@
#include <boost/geometry/views/detail/range_type.hpp>
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/util/order_as_direction.hpp>
namespace boost { namespace geometry {
diff --git a/3party/boost/boost/geometry/views/detail/points_view.hpp b/3party/boost/boost/geometry/views/detail/points_view.hpp
index 3f6fdc6093..a06084216b 100644
--- a/3party/boost/boost/geometry/views/detail/points_view.hpp
+++ b/3party/boost/boost/geometry/views/detail/points_view.hpp
@@ -36,6 +36,7 @@ class points_view
// 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".
+ // ALTERNATIVE: use boost:array and its iterators
struct points_iterator
: public boost::iterator_facade
<
@@ -105,7 +106,7 @@ class points_view
}
Point const* m_points;
- int m_index;
+ difference_type m_index;
};
public :