LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/ili - ilihelper.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 54 44 81.5 %
Date: 2012-12-26 Functions: 2 2 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ilihelper.cpp 24609 2012-06-25 15:21:10Z pka $
       3                 :  *
       4                 :  * Project:  Interlis 1/2 Translator
       5                 :  * Purpose:  Helper functions for Interlis reader
       6                 :  * Author:   Pirmin Kalberer, Sourcepole AG
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2004, Pirmin Kalberer, Sourcepole AG
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : 
      31                 : #include "ilihelper.h"
      32                 : 
      33                 : 
      34                 : CPL_CVSID("$Id: ilihelper.cpp 24609 2012-06-25 15:21:10Z pka $");
      35                 : 
      36                 : 
      37              15 : OGRPoint *getARCCenter(OGRPoint *ptStart, OGRPoint *ptArc, OGRPoint *ptEnd) {
      38                 :   // FIXME precision
      39              15 :   double bx = ptStart->getX(); double by = ptStart->getY();
      40              15 :   double cx = ptArc->getX(); double cy = ptArc->getY();
      41              15 :   double dx = ptEnd->getX(); double dy = ptEnd->getY();
      42                 :   double temp, bc, cd, det, x, y;
      43                 : 
      44              15 :   temp = cx*cx+cy*cy;
      45              15 :   bc = (bx*bx + by*by - temp)/2.0;
      46              15 :   cd = (temp - dx*dx - dy*dy)/2.0;
      47              15 :   det = (bx-cx)*(cy-dy)-(cx-dx)*(by-cy);
      48                 : 
      49              15 :   OGRPoint *center = new OGRPoint();
      50                 : 
      51              15 :   if (fabs(det) < 1.0e-6) { // could not determin the determinante: too small
      52               0 :     return center;
      53                 :   }
      54              15 :   det = 1/det;
      55              15 :   x = (bc*(cy-dy)-cd*(by-cy))*det;
      56              15 :   y = ((bx-cx)*cd-(cx-dx)*bc)*det;
      57                 : 
      58              15 :   center->setX(x);
      59              15 :   center->setY(y);
      60                 : 
      61              15 :   return center;
      62                 : }
      63                 : 
      64              15 : void interpolateArc(OGRLineString* line, OGRPoint *ptStart, OGRPoint *ptOnArc, OGRPoint *ptEnd, double arcIncr) {
      65              15 :   OGRPoint *center = getARCCenter(ptStart, ptOnArc, ptEnd);
      66                 : 
      67              15 :   double cx = center->getX(); double cy = center->getY();
      68              15 :   double px = ptOnArc->getX(); double py = ptOnArc->getY();
      69              15 :   double r = sqrt((cx-px)*(cx-px)+(cy-py)*(cy-py));
      70                 : 
      71                 :   //assure minimal chord length (0.002m???)
      72              15 :   double myAlpha = 2.0*acos(1.0-0.002/r);      
      73              15 :   if (myAlpha < arcIncr)  {
      74               0 :       arcIncr = myAlpha;
      75                 :   }
      76                 : 
      77              15 :   double a1 = atan2(ptStart->getY() - cy, ptStart->getX() - cx);
      78              15 :   double a2 = atan2(py - cy, px - cx);
      79              15 :   double a3 = atan2(ptEnd->getY() - cy, ptEnd->getX() - cx);
      80                 : 
      81                 :   double sweep;
      82                 : 
      83                 :   // Clockwise
      84              30 :   if(a1 > a2 && a2 > a3) {
      85              15 :     sweep = a3 - a1;
      86                 :   }
      87                 :   // Counter-clockwise
      88               0 :   else if(a1 < a2 && a2 < a3) {
      89               0 :     sweep = a3 - a1;
      90                 :   }
      91                 :   // Clockwise, wrap
      92               0 :   else if((a1 < a2 && a1 > a3) || (a2 < a3 && a1 > a3)) {
      93               0 :     sweep = a3 - a1 + 2*PI;
      94                 :   }
      95                 :   // Counter-clockwise, wrap
      96               0 :   else if((a1 > a2 && a1 < a3) || (a2 > a3 && a1 < a3)) {
      97               0 :     sweep = a3 - a1 - 2*PI;
      98                 :   }
      99                 :   else {
     100               0 :     sweep = 0.0;
     101                 :   }
     102                 : 
     103              15 :   int ptcount = ceil(fabs(sweep/arcIncr));
     104                 : 
     105              15 :   if(sweep < 0) arcIncr *= -1.0;
     106                 : 
     107              15 :   double angle = a1;
     108                 : 
     109            3061 :   for(int i = 0; i < ptcount - 1; i++) {
     110            3046 :     angle += arcIncr;
     111                 : 
     112            3046 :     if(arcIncr > 0.0 && angle > PI) angle -= 2*PI;
     113            3046 :     if(arcIncr < 0.0 && angle < -1*PI) angle -= 2*PI;
     114                 : 
     115            3046 :     double x = cx + r*cos(angle);
     116            3046 :     double y = cy + r*sin(angle);
     117                 :    
     118            3046 :     line->addPoint(x, y, 0);
     119                 : 
     120                 :    
     121            3046 :     if((angle < a2) && ((angle + arcIncr) > a2)) {
     122               0 :        line->addPoint(ptOnArc);
     123                 :     }
     124                 : 
     125            3046 :     if((angle > a2) && ((angle + arcIncr) < a2)) {
     126              15 :        line->addPoint(ptOnArc);
     127                 :     }
     128                 :    
     129                 :   }
     130              15 :   line->addPoint(ptEnd);
     131              15 :   delete center;
     132              15 : }
     133                 : 

Generated by: LCOV version 1.7