Mail.Ru Maps рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдПрдХ рдХрд╛рд░реНрдп рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ,
WKB рдкреНрд░рд╛рд░реВрдк рдХреЛ рдкрдврд╝рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рдЧрдпрд╛ред рдмреЗрд╢рдХ, рдЖрдк
GDAL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЕрдиреНрдп рд╕рднреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдмреЗрдорд╛рдиреА рдереАрдВред рдЗрд╕рд▓рд┐рдП рдЗрд╕ рдЫреЛрдЯреА рд╕рд╛рдЗрдХрд┐рд▓ рдХрд╛ рдЬрдиреНрдо рд╣реБрдЖред
рдореИрдВ рддреБрд░рдВрдд рдЪреЗрддрд╛рд╡рдиреА рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░ рд▓рд╛рдЧреВ рдХреА рдЬрд╛рддреА рд╣реИ рдФрд░ рдХреЗрд╡рд▓ рдмреБрдирд┐рдпрд╛рджреА рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕рдорд░реНрдерди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреИрд╕реЗ:
- рдмрд┐рдВрджреБ
- рд▓рд╛рдЗрди
- рднреВрдорд┐
- рдмрд╣реБ
- multipolygon
рдПрдХ рд╢рдмреНрдж рдореЗрдВ рдЯреНрд░рд╛рдВрд╕рдХреЛрдбрд┐рдВрдЧ рдмрд╛рдЗрдЯ рдСрд░реНрдбрд░ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИред рдФрд░ рдЗрд╕рд▓рд┐рдП - рдЗрд╕реЗ рд▓реЗрдВ рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдПрд╕рдЯреАрдПрд▓ рдЬреИрд╕реЗ рдХрдВрдЯреЗрдирд░ рдХреЗ рд░реВрдк рдореЗрдВ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдЖрд╡рд░рдг рд╡рд░реНрдЧ рднреА рдЙрдкрдпреЛрдЧреА рд╣реИ; рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЙрд╕реЗ
рдпрд╣рд╛рдВ рд╕реЗ рд▓реЗ рдЬрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛
рд╣реИ ред рдФрд░ рдЬреНрдпрд╛рдорд┐рддреАрдп рдЖрджрд┐рдореЛрдВ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рд╛рдердорд┐рдХ рдХрдХреНрд╖рд╛рдПрдВ: рдЕрдВрдХ рдФрд░ рдЖрдпрддреЗрдВред
рдХреНрд▓рд╛рд╕ рдХреЛрдбnamespace ml { struct point_d { double x; double y; }; inline std::ostream & operator << (std::ostream &s, point_d const &p) { return s << px << ", " << py; } inline double distance(point_d const &p1, point_d const &p2) { double dx = (p1.x-p2.x); double dy = (p1.y-p2.y); return sqrt(dx*dx+dy*dy); } struct rect_d { point_d min; point_d max; static rect_d void_rect() { return rect_d(std::numeric_limits<T>::max(),std::numeric_limits<T>::max(), -std::numeric_limits<T>::max(),-std::numeric_limits<T>::max()); } bool empty() const { return (*this == rect_d::void_rect() || (width()==0 && height()==0)); } inline double height() const { return fabs(max.y-min.y); } inline double width() const { return fabs(max.x-min.x); } rect_d & extend(const rect_d &r) { if(r.empty()) return *this; min.x = std::min(min.x,std::min(r.min.x,r.max.x)); min.y = std::min(min.y,std::min(r.min.y,r.max.y)); max.x = std::max(max.x,std::max(r.min.x,r.max.x)); max.y = std::max(max.y,std::max(r.min.y,r.max.y)); return *this; } template< typename C > rect_d & bounds( C begin, C end) { for(; begin != end; ++begin) { min.x = std::min(min.x,begin->x); min.y = std::min(min.y,begin->y); max.x = std::max(max.x,begin->x); max.y = std::max(max.y,begin->y); } return *this; } }; inline std::ostream & operator << (std::ostream &s,const rect_d &r) { return s << '[' << r.min << ',' << r.max << ']'; } }
рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкрд╣рд▓реЗ WKB рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд▓реЛрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕реЗ рд╡рд┐рд╡реЗрдХ рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреМрди рдХрд░реЗрдЧрд╛ред
рд▓рд┐рдЦрд┐рдд рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓рдЧрднрдЧ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдерд╛:
char *data = .... ml::wkb shape(data); std::cout << ml::wkb::type_to_text(shape.type()) << std::endl; std::cout << shape.bounds() << std::endl;
рдкрд╣рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рдорд╛рдереЗ рдореЗрдВ рдПрдХ рд╕рдорд╛рдзрд╛рди рдирд┐рдХрд▓рд╛, рдФрд░ рдЗрд╕ рддрд░рд╣ рджреЗрдЦрд╛:
рдкрд╣рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг namespace ml { class wkb { char const * m_data; public: enum type_e{ wkb_point = 1, wkb_line_string = 2, wkb_polygon = 3, wkb_multi_point = 4, wkb_multi_line_string = 5, wkb_multi_polygon = 6, wkb_geometry_collection = 7 }; static char const *type_to_text(type_e type) { switch (type) { case wkb_point: return "wkb_point"; case wkb_line_string: return "wkb_line_string"; case wkb_polygon: return "wkb_polygon"; case wkb_multi_point: return "wkb_multi_point"; case wkb_multi_line_string: return "wkb_multi_line_string"; case wkb_multi_polygon: return "wkb_multi_polygon"; case wkb_geometry_collection: return "wkb_geometry_collection"; default: return "unknown"; } } typedef container<ml::point_d> line; wkb(char const *data) : m_data(data) {} wkb & operator = (wkb const &d) { m_data = d.m_data; return *this; } inline char byte_order() const { return m_data[0]; } inline type_e type() const { return (type_e)*(int*)&m_data[1]; } inline int size() const { return *(int*)&m_data[5]; } line linestring() const { return line((line::value_type*)&m_data[9], size()); } ml::point_d const & point() const { return *(ml::point_d*)&m_data[5]; } wkb linestring(size_t index) const { size_t offset = 9; for(size_t i=0; i<size(); ++i) { wkb l(&m_data[offset]); if (i == index) return l; offset += 9 + 16 * l.size(); } return wkb(0); } line ring(size_t index) const { size_t offset = 9; for(size_t i=0; i<size(); ++i) { int point_count = *(int*)&m_data[offset]; if(i == index) return line((line::value_type*)&m_data[offset+4], point_count); offset = offset + 4 + 16*point_count; } return line(NULL,(size_t)0); } wkb polygon(size_t index) const { size_t offset = 9; for(size_t i=0; i<this->size(); ++i) { wkb o(&m_data[offset]); if(i == index) return o; for(size_t j=0; j<o.size(); ++j) offset += o.ring(j).size() * 16 + 4; offset += 9; } return wkb(0); } ml::rect_d bounds() const { ml::rect_d r(ml::rect_d::void_rect()); switch (type()) { case wkb_polygon: { for(size_t i=0; i < size(); ++i) { line l = ring(i); r.bounds(l.begin(),l.end()); } } break; case wkb_multi_polygon: { for(size_t i=0; i < size(); ++i) { r.extend(polygon(i).bounds()); } } break; case wkb_point: { r.min.x = r.max.x = *(double*)&m_data[5]; r.min.y = r.max.y = *(double*)&m_data[13]; } break; case wkb_line_string: { line l = linestring(); r.bounds(l.begin(),l.end()); } break; case wkb_multi_line_string: { for(size_t i=0; i < size(); ++i) { r.extend(linestring(i).bounds()); } } break; default: break; } return r; } }; }
рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд┐рдпрд╛ рдФрд░ рд╕рд╣реА рдкрд░рд┐рдгрд╛рдо рджрд┐рдП, рд▓реЗрдХрд┐рди (рдЬрд╣рд╛рдВ рдпрд╣ "рд▓реЗрдХрд┐рди" рдмрд┐рдирд╛), рдЬрдм рд╣рдореЗрдВ рдХрдИ рдорд┐рд▓рд┐рдпрди рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдерд╛, рддреЛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рдЦрд░реНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╕рдордп рд╣рдореЗрдВ рд╕реВрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рдерд╛ред
рдкреНрд░реЛрдлрд╛рдЗрд▓рд┐рдВрдЧ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рдХрд┐ WKB рдХреЗ рдЖрд╡рд╢реНрдпрдХ рд╣рд┐рд╕реНрд╕реЗ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдореЗрдВ рдмрд╣реБрдд рд╕рдордп рдХреНрдпреЛрдВ рд▓рдЧрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдвреЗрд░ рдкрд░ рдХрдИ рдордзреНрдпрд╡рд░реНрддреА рд╡рд╕реНрддреБрдПрдВ рдмрдирд╛рдИ рдЧрдИрдВ рдФрд░ рдПрдХ рдЫреЛрдЯреА рд▓реЗрдХрд┐рди рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рднреА рдЙрдкрд▓рдмреНрдз рдереАред рд╕рд┐рд░ рдХреЗ рдкрд┐рдЫрд▓реЗ рд╣рд┐рд╕реНрд╕реЗ рдореЗрдВ рдЦрд░реЛрдВрдЪ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдордиреЗ рдХреЛрдб рдХреЛ рдХреБрдЫ рд╣рдж рддрдХ рдкрд░рд┐рд╖реНрдХреГрдд рдХрд░рдиреЗ рдФрд░ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпреЛрдВ рд╕реЗред рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рд╡рд░реНрддрдорд╛рди рддрддреНрд╡ рдХреЗ рдЕрдВрдд рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдФрд░ рдЕрдЧрд▓реЗ рддрддреНрд╡ рдХреА рд╢реБрд░реБрдЖрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЬреЛрдбрд╝рд╛:
inline const char * end_of_ring(const char *ptr) const { return ptr + 4 + (*(unsigned int *)(ptr) * 16); } inline const char * end_of_polygon(const char *ptr) const { for (size_t sz = *(unsigned int*)((ptr+=9)-4);sz--;) ptr += (*(unsigned int *)(ptr) * 16) + 4; return ptr; }
рдЙрд╕рдХреЗ рдмрд╛рдж, рддрддреНрд╡реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗ рдЧрдП, рд╡реЗ рд╕рд░рд▓ рдФрд░ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдП:
рдЫрд┐рдкрд╛ рд╣реБрдЖ рдкрд╛рда line linestring() const { return line((line::value_type*)(m_data+9), size()); } ml::point_d const & point() const { return *(ml::point_d*)(m_data+5); } wkb linestring(size_t index) const { assert(index>=0 && index<m_size); const char *ptr = m_data+9; while (index--) { ptr += 9 + (*(unsigned int*)(ptr+5) * 16); } return wkb(ptr); } wkb polygon(size_t index) const { assert(index>=0 && index<m_size); const char *ptr = m_data+9; while (index--) { ptr = end_of_polygon(ptr); } return wkb(ptr); } line ring(size_t index) const { assert(index>=0 && index<m_size); const char *ptr = m_data+9; while (index--) { ptr = end_of_ring(ptr); } return line((line::value_type*)(ptr+4),(line::value_type*)end_of_ring(ptr)); }
рдЗрд╕рд╕реЗ рдЙрддреНрдкрд╛рджрдХрддрд╛ рдкрд╣рд▓реЗ рд╣реА рдмрдврд╝ рдЧрдИ рд╣реИред рд▓реЗрдХрд┐рди рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдмрд┐рдВрджреБрдУрдВ рдХреА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдзрд┐ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдФрд░ рд╕реБрд╡рд┐рдзрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдерд╛:
рдЫрд┐рдкрд╛ рд╣реБрдЖ рдкрд╛рда template< typename T > T & apply( T & func) const { switch (type()) { case wkb_polygon: { const char * ptr = m_data+9; for(size_t i=0; i<m_size; ++i) { ml::point_d *begin = (ml::point_d*)(ptr+4); ml::point_d *end = begin + *(unsigned int *)(ptr); ptr = (const char *)end; func(begin,end); } } break; case wkb_multi_polygon: { const char * ptr = m_data+9; for(size_t i=0; i<m_size; ++i) { for (size_t sz = *(unsigned int*)((ptr+=9)-4);sz--;) { ml::point_d *begin = (ml::point_d*)(ptr+4); ml::point_d *end = begin + *(unsigned int *)(ptr); ptr = (const char *)end; func(begin,end); } } } break; case wkb_point: { ml::point_d *begin = (ml::point_d*)(m_data+5); ml::point_d *end = begin + 1; func(begin,end); } break; case wkb_line_string: { ml::point_d *begin = (ml::point_d*)(m_data+9); ml::point_d *end = begin + size(); func(begin,end); } break; case wkb_multi_line_string: { const char * ptr = m_data+9; for(size_t i=0; i<m_size; ++i) { ml::point_d *begin = (ml::point_d*)(ptr+9); ml::point_d *end = begin + *(unsigned int *)(ptr+5); ptr = (const char *)end; func(begin,end); } } break; default: break; } return func; }
рд╣рдордиреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЗ рд╕реЗ рд╡рд░реНрдгрди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЖрдпрдд рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдлрд╝рдирдХрд╛рд░ рдХреЛ рдЬреЛрдбрд╝рд╛:
struct bounds_counter { ml::rect_d r; bounds_counter() : r(ml::rect_d::void_rect()) {} void operator()(ml::point_d const *begin, ml::point_d const *end) { r.bounds(begin,end); } ml::rect_d const & bounds() const { return r; } };
рдкреБрдирд░реНрд▓реЗрдЦрди рдХреЗ рдмрд╛рдж рд╕реАрдорд╛ рд╡рд┐рдзрд┐ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд▓рдЧреА:
ml::rect_d ml::wkb::bounds() const { struct bounds_counter { ml::rect_d r; bounds_counter() : r(ml::rect_d::void_rect()) {} void operator()(ml::point_d const *begin, ml::point_d const *end) { r.bounds(begin,end); } ml::rect_d const & bounds() const { return r; } }; bounds_counter b; return apply(b).bounds(); }
рдпрд╣ рд╡рд┐рдХрд▓реНрдк g ++ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдпрд╣ рдорд╛рдирдХреЛрдВ рдХрд╛ рд╕рдЦреНрддреА рд╕реЗ рдкрд╛рд▓рди рдХрд░рддрд╛ рд╣реИ:
14.3.1 / 2: рдПрдХ рд╕реНрдерд╛рдиреАрдп рдкреНрд░рдХрд╛рд░, рдмрд┐рдирд╛ рд▓рд┐рдВрдХреЗрдЬ рд╡рд╛рд▓рд╛ рдПрдХ рдкреНрд░рдХрд╛рд░, рдПрдХ рдЕрдирд╛рдо рдкреНрд░рдХрд╛рд░ рдпрд╛ рдЗрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рд╕реЗ рдХрдВрдкрд╛рдЙрдВрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЯреЗрдореНрдкрд▓реЗрдЯ-рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкрд▓реЗрдЯ-рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рд▓реЗрдХрд┐рди рдпрд╣ Clang рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╣реИ, рдФрд░ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдЦреЛрдЬ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ MSVC ++ (рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ, рд╣рдордиреЗ рдЬрд╛рдВрдЪ рдирд╣реАрдВ рдХреА)ред
рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХрддрд╛ рдФрд░ рд╢реБрджреНрдзрддрд╛ рдХреЗ рд▓рд┐рдП, рдПрдХ рдлрд╝рдирдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЛ рдПрдХ рдЕрдирд╛рдо рдирд╛рдорд╕реНрдерд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПредрд╕рднреА рд╕реБрдзрд╛рд░реЛрдВ рдХреЗ рдмрд╛рдж, рдХрд╛рд░реНрдп рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рд▓рдЧрднрдЧ рдЪрд╛рд░ рдЧреБрдирд╛ рдХрдо рд╣реЛ рдЧрдпрд╛ред рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, JSON рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рд▓рд┐рдЦрдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдерд╛:
рдЫрд┐рдкрд╛ рд╣реБрдЖ рдкрд╛рда std::string ml::wkb::to_geo_json() const { struct point_formatter { std::stringstream &ss; unsigned int counter; bool parts; point_formatter(std::stringstream &s) : ss(s),counter(0), parts(false) {} void operator() (ml::point_d const *begin, ml::point_d const *end) { if (parts) ss << (counter ? ",[" : "["); ss << "[" << begin->x << "," << begin->y << "]"; for(++begin;begin != end;++begin){ ss << ",[" << begin->x << "," << begin->y << "]"; } if (parts) ss << "]"; ++counter; } point_formatter & make_parts(bool p) {parts = p; counter = 0; return *this;} }; std::stringstream ss; point_formatter fmt(ss); ss << std::fixed << std::showpoint << std::setprecision(6); ss << "{"; switch(type()) { case wkb_point: { ss << "\"type\":\"Point\",\"coordinates\":"; apply(fmt); } break; case wkb_line_string: { ss << "\"type\":\"LineString\",\"coordinates\": ["; apply(fmt); ss << "]"; } break; case wkb_multi_line_string: { ss << "\"type\":\"MultiLineString\",\"coordinates\": ["; apply(fmt.make_parts(true)); ss << "]"; } break; case wkb_polygon: { ss << "\"type\":\"Polygon\",\"coordinates\": ["; apply(fmt.make_parts(true)); ss << "]"; } break; case wkb_multi_polygon: { ss << "\"type\":\"MultiPolygon\",\"coordinates\": ["; for(size_t i=0; i < size(); ++i) { ss << (i ? ",[" : "["); polygon(i).apply(fmt.make_parts(true)); ss << "]"; } ss << "]"; } break; default: break; } ss << "}"; return ss.str(); }
рдкрд░рд┐рдгрд╛рдо WKB рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рдлреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╡рд░реНрдЧ рд╣реИред рд╡рд╕реНрддреБрдУрдВ рдкрд░ рдирдП рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛ рдЧрдпрд╛ рд╣реИред рдирд┐рд░реНрдгрд╛рдпрдХ рдкреНрд░рджрд░реНрд╢рди рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ред
рд▓реЗрдЦ рдХреЗ рд╕рднреА рдХреЛрдб рдХреЛ
рдпрд╣рд╛рдВ рдФрд░
рдпрд╣рд╛рдВ рд▓рд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛
рд╣реИ ред
рдПрд░реНрд╢реЛрд╡ рд╕рд░реНрдЧреЗрдИ,
рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдореИрдкреНрд╕ Mail.Ru