예제 #1
0
    /* summarized distance centroid */
    void label_position3(double *x, double *y) const
    {
        if (type_ == LineString || type_ == MultiLineString)
        {
            middle_point(x,y);
            return;
        }

        unsigned i = 0;
        double l = 0.0;
        double tl = 0.0;
        double cx = 0.0;
        double cy = 0.0;
        double x0 = 0.0;
        double y0 = 0.0;
        double x1 = 0.0;
        double y1 = 0.0;
        unsigned size = cont_.size();   
        for (i = 0; i < size-1; i++)
        {
            cont_.get_vertex(i,&x0,&y0);
            cont_.get_vertex(i+1,&x1,&y1);
            l = distance(x0,y0,x1,y1);
            cx += l * (x1 + x0)/2;
            cy += l * (y1 + y0)/2;
            tl += l;
        }
        *x = cx / tl;
        *y = cy / tl;
    }
예제 #2
0
    /* center of gravity centroid
      - best visually but does not work with multipolygons
    */
    void label_position(double *x, double *y) const
    {
        if (type_ == LineString || type_ == MultiLineString)
        {
            middle_point(x,y);
            return;
        }

        unsigned size = cont_.size();
        if (size < 3) 
        {
            cont_.get_vertex(0,x,y);
            return;
        }
           
        double ai;
        double atmp = 0;
        double xtmp = 0;
        double ytmp = 0;
        double x0 =0;
        double y0 =0;
        double x1 =0;
        double y1 =0;
        double ox =0;
        double oy =0;
           
        unsigned i;
           
        // Use first point as origin to improve numerical accuracy
        cont_.get_vertex(0,&ox,&oy);

        for (i = 0; i < size-1; i++)
        {
            cont_.get_vertex(i,&x0,&y0);
            cont_.get_vertex(i+1,&x1,&y1);
               
            x0 -= ox; y0 -= oy;
            x1 -= ox; y1 -= oy;

            ai = x0 * y1 - x1 * y0;
            atmp += ai;
            xtmp += (x1 + x0) * ai;
            ytmp += (y1 + y0) * ai;
        }    
        if (atmp != 0)
        {
            *x = (xtmp/(3*atmp)) + ox;
            *y = (ytmp/(3*atmp)) + oy;
            return;
        }
        *x=x0;
        *y=y0;            
    }
예제 #3
0
 bool hit_test(value_type x, value_type y, double tol) const
 {      
     if (cont_.size() == 1) {
         // Handle points
         double x0, y0;
         cont_.get_vertex(0, &x0, &y0);
         return distance(x, y, x0, y0) <= fabs(tol);
     } else if (cont_.size() > 1) {
         bool inside=false;
         double x0=0;
         double y0=0;
         rewind(0);
         vertex(&x0, &y0);
             
         unsigned command;
         double x1,y1;
         while (SEG_END != (command=vertex(&x1, &y1)))
         {
             if (command == SEG_MOVETO)
             {
                 x0 = x1;
                 y0 = y1;
                 continue;
             }               
             if ((((y1 <= y) && (y < y0)) ||
                  ((y0 <= y) && (y < y1))) &&
                 ( x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1))
                 inside=!inside;
             x0=x1;
             y0=y1;
         }
         return inside;
     }
     return false;
 } 
예제 #4
0
 void middle_point(double *x, double *y) const
 {
     // calculate mid point on path
     double x0=0;
     double y0=0;
     double x1=0;
     double y1=0;
   
     unsigned size = cont_.size();
     if (size == 1)
     {
         cont_.get_vertex(0,x,y); 
     }
     else if (size == 2)
     {
         cont_.get_vertex(0,&x0,&y0);
         cont_.get_vertex(1,&x1,&y1);
         *x = 0.5 * (x1 + x0);
         *y = 0.5 * (y1 + y0);    
     }
     else
     {
         double len=0.0;
         for (unsigned pos = 1; pos < size; ++pos)
         {
             cont_.get_vertex(pos-1,&x0,&y0);
             cont_.get_vertex(pos,&x1,&y1);
             double dx = x1 - x0;
             double dy = y1 - y0;
             len += std::sqrt(dx * dx + dy * dy);
         }
         double midlen = 0.5 * len;
         double dist = 0.0;
         for (unsigned pos = 1; pos < size;++pos)
         {
             cont_.get_vertex(pos-1,&x0,&y0);
             cont_.get_vertex(pos,&x1,&y1);
             double dx = x1 - x0;
             double dy = y1 - y0; 
             double seg_len = std::sqrt(dx * dx + dy * dy);
             if (( dist + seg_len) >= midlen)
             {
                 double r = (midlen - dist)/seg_len;
                 *x = x0 + (x1 - x0) * r;
                 *y = y0 + (y1 - y0) * r;
                 break;
             }
             dist += seg_len;
         }
     }  
 }
예제 #5
0
 unsigned get_vertex(unsigned pos, double* x, double* y) const
 {
     return cont_.get_vertex(pos, x, y);
 }         
예제 #6
0
 unsigned vertex(double* x, double* y) const
 {
     return cont_.get_vertex(itr_++,x,y);
 }         
예제 #7
0
파일: geometry.hpp 프로젝트: rjw57/mapnik
 unsigned vertex(std::size_t index, double* x, double* y) const
 {
     return cont_.get_vertex(index, x, y);
 }