Пример #1
0
 OGRLineString* make()
 {
     OGRLineString* poLineString = new OGRLineString();
     
     poLineString->addPoint(1.0, 2.0, 3.0);
     poLineString->addPoint(1.1, 2.1, 3.1);
     poLineString->addPoint(1.2, 2.2, 3.2);
     
     return poLineString;
 }
Пример #2
0
OGRFeature*
     OGRXPlaneAirwaySegmentLayer::AddFeature(const char* pszAirwaySegmentName,
                                             const char* pszFirstPointName,
                                             const char* pszSecondPointName,
                                             double dfLat1,
                                             double dfLon1,
                                             double dfLat2,
                                             double dfLon2,
                                             int    bIsHigh,
                                             int    nBaseFL,
                                             int    nTopFL)
{
    int nCount = 0;
    OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
    if (fabs(dfLon1 - dfLon2) < 270)
    {
        OGRLineString* lineString = new OGRLineString();
        lineString->addPoint(dfLon1, dfLat1);
        lineString->addPoint(dfLon2, dfLat2);
        poFeature->SetGeometryDirectly( lineString );
    }
    else
    {
        /* Crossing antemeridian */
        OGRMultiLineString* multiLineString = new OGRMultiLineString();
        OGRLineString* lineString1 = new OGRLineString();
        OGRLineString* lineString2 = new OGRLineString();
        double dfLatInt;
        lineString1->addPoint(dfLon1, dfLat1);
        if (dfLon1 < dfLon2)
        {
            dfLatInt = dfLat1 + (dfLat2 - dfLat1) * (-180 - dfLon1) / ((dfLon2 - 360) - dfLon1);
            lineString1->addPoint(-180, dfLatInt);
            lineString2->addPoint(180, dfLatInt);
        }
        else
        {
            dfLatInt = dfLat1 + (dfLat2 - dfLat1) * (180 - dfLon1) / ((dfLon2 + 360) - dfLon1);
            lineString1->addPoint(180, dfLatInt);
            lineString2->addPoint(-180, dfLatInt);
        }
        lineString2->addPoint(dfLon2, dfLat2);
        multiLineString->addGeometryDirectly( lineString1 );
        multiLineString->addGeometryDirectly( lineString2 );
        poFeature->SetGeometryDirectly( multiLineString );
    }
    poFeature->SetField( nCount++, pszAirwaySegmentName );
    poFeature->SetField( nCount++, pszFirstPointName );
    poFeature->SetField( nCount++, pszSecondPointName );
    poFeature->SetField( nCount++, bIsHigh );
    poFeature->SetField( nCount++, nBaseFL );
    poFeature->SetField( nCount++, nTopFL );

    RegisterFeature(poFeature);

    return poFeature;
}
Пример #3
0
OGRFeature *OGRSEGUKOOALineLayer::GetNextRawFeature()
{
    if( bEOF )
        return nullptr;

    /* Merge points of base layer that have same value for attribute(0) */
    /* into a single linestring */

    OGRFeature* poFeature = nullptr;
    OGRLineString* poLS = nullptr;

    if (poNextBaseFeature == nullptr)
        poNextBaseFeature = poBaseLayer->GetNextFeature();

    while(poNextBaseFeature != nullptr)
    {
        if (poNextBaseFeature->IsFieldSetAndNotNull(0) &&
            poNextBaseFeature->GetFieldAsString(0)[0] != '\0')
        {
            if (poFeature != nullptr &&
                strcmp(poFeature->GetFieldAsString(0),
                    poNextBaseFeature->GetFieldAsString(0)) != 0)
            {
                poFeature->SetGeometryDirectly(poLS);
                return poFeature;
            }

            OGRGeometry* poGeom =
                poNextBaseFeature->GetGeometryRef();
            OGRPoint* poPoint = poGeom ? poGeom->toPoint(): nullptr;
            if (poPoint != nullptr)
            {
                if (poFeature == nullptr)
                {
                    poFeature = new OGRFeature(poFeatureDefn);
                    poFeature->SetFID(nNextFID ++);
                    poFeature->SetField(0,
                        poNextBaseFeature->GetFieldAsString(0));
                    poLS = new OGRLineString();
                    if (poBaseLayer->GetSpatialRef())
                        poLS->assignSpatialReference(
                                    poBaseLayer->GetSpatialRef());
                }

                poLS->addPoint(poPoint);
            }
        }

        delete poNextBaseFeature;
        poNextBaseFeature = poBaseLayer->GetNextFeature();
    }

    bEOF = true;
    if( poFeature )
        poFeature->SetGeometryDirectly(poLS);
    return poFeature;
}
Пример #4
0
OGRGeometry* BuildMultiLine(OGRGeometry* geometry){
  double simplify = 0.01;
  OGRPolygon* poly = dynamic_cast<OGRPolygon *>(geometry->Simplify(simplify));
  while(poly == NULL){
    simplify -= 0.001;
    poly = dynamic_cast<OGRPolygon *>(geometry->Simplify(simplify));
  }

  Polygon skeleton = GeomToPoly(poly);
  if(skeleton.size() < 3) return NULL;

  if(skeleton.is_counterclockwise_oriented() == 0) { skeleton.reverse_orientation(); }
  std::cout << "\nSkeletonizing." << std::endl;
  SsPtr iss = CGAL::create_interior_straight_skeleton_2(skeleton);
  if(!iss.get()) IsValid(NULL, "No skeleton!");
  std::cout << "Computed Skeleton." << std::endl;
  OGRLineString* line = NULL;
  // And finally append points to our shapefile
  double edge = 0;
  Ss::Halfedge_iterator vi = iss->halfedges_begin();
  for(; vi != iss->halfedges_end(); ++vi){
    OGRPoint point  = OGRPoint(vi->vertex()->point().x(), vi->vertex()->point().y());
    OGRPoint npoint = OGRPoint(vi->next()->vertex()->point().x(), vi->next()->vertex()->point().y());
    OGRLineString segment = OGRLineString();
    segment.addPoint(&point);
    segment.addPoint(&npoint);
    if(line == NULL) { line = new OGRLineString; }
    OGRLineString *tmp;
    ++edge;
    if(vi->vertex()->is_skeleton() && vi->next()->vertex()->is_skeleton() && segment.Within(geometry)) {
      tmp = reinterpret_cast<OGRLineString *>(line->Union(&segment));
      if(tmp != NULL) {
        std::cout << "\r" <<  (int) (edge / (double)iss->size_of_halfedges() * 100.0) << "% ";
        std::cout.flush();
        delete line;
        line = tmp;
      }
    }
  }
  OGRGeometryFactory::destroyGeometry(poly);
  return line;
}
Пример #5
0
OGRFeature *OGRSEGUKOOALineLayer::GetNextRawFeature()
{
    if (bEOF)
        return NULL;

    /* Merge points of base layer that have same value for attribute(0) */
    /* into a single linestring */

    OGRFeature* poFeature = NULL;
    OGRLineString* poLS = NULL;

    if (poNextBaseFeature == NULL)
        poNextBaseFeature = poBaseLayer->GetNextFeature();

    while(poNextBaseFeature != NULL)
    {
        if (poNextBaseFeature->IsFieldSet(0) &&
            poNextBaseFeature->GetFieldAsString(0)[0] != '\0')
        {
            if (poFeature != NULL &&
                strcmp(poFeature->GetFieldAsString(0),
                    poNextBaseFeature->GetFieldAsString(0)) != 0)
            {
                return poFeature;
            }

            OGRPoint* poPoint =
                (OGRPoint*) poNextBaseFeature->GetGeometryRef();
            if (poPoint != NULL)
            {
                if (poFeature == NULL)
                {
                    poFeature = new OGRFeature(poFeatureDefn);
                    poFeature->SetFID(nNextFID ++);
                    poFeature->SetField(0,
                        poNextBaseFeature->GetFieldAsString(0));
                    poLS = new OGRLineString();
                    if (poBaseLayer->GetSpatialRef())
                        poLS->assignSpatialReference(
                                    poBaseLayer->GetSpatialRef());
                    poFeature->SetGeometryDirectly(poLS);
                }

                poLS->addPoint(poPoint);
            }
        }

        delete poNextBaseFeature;
        poNextBaseFeature = poBaseLayer->GetNextFeature();
    }

    bEOF = TRUE;
    return poFeature;
}
Пример #6
0
/*!
  \brief Load geometry (linestring SBP layer)

  \todo Really needed?

  \return TRUE on success or FALSE on failure
*/
bool VFKFeature::LoadGeometryLineStringSBP()
{
    int id, idxId, idxBp_Id, idxPCB, ipcb;
    
    VFKDataBlock *poDataBlockPoints;
    VFKFeature   *poPoint, *poLine;
    
    OGRLineString OGRLine;
    
    poDataBlockPoints = (VFKDataBlock *) m_poDataBlock->GetReader()->GetDataBlock("SOBR");
    if (!poDataBlockPoints)
        return FALSE;
    
    idxId    = poDataBlockPoints->GetPropertyIndex("ID");
    idxBp_Id = m_poDataBlock->GetPropertyIndex("BP_ID");
    idxPCB   = m_poDataBlock->GetPropertyIndex("PORADOVE_CISLO_BODU");
    if (idxId < 0 || idxBp_Id < 0 || idxPCB < 0)
        return false;
    
    poLine = this;
    while (TRUE)
    {
        id   = poLine->GetProperty(idxBp_Id)->GetValueI();
        ipcb = poLine->GetProperty(idxPCB)->GetValueI();
        if (OGRLine.getNumPoints() > 0 && ipcb == 1)
        {
            m_poDataBlock->GetPreviousFeature(); /* push back */
            break;
        }
        
        poPoint = poDataBlockPoints->GetFeature(idxId, id);
        if (!poPoint)
        {
            continue;
        }
        OGRPoint *pt = (OGRPoint *) poPoint->GetGeometry();
        OGRLine.addPoint(pt);
        
        poLine = (VFKFeature *) m_poDataBlock->GetNextFeature();
        if (!poLine)
            break;
    };
    
    OGRLine.setCoordinateDimension(2); /* force 2D */
    SetGeometry(&OGRLine);
    
    /* reset reading */
    poDataBlockPoints->ResetReading();
    
    return TRUE;
}
Пример #7
0
OGRFeature* GTMTrackLayer::GetNextFeature()
{
    if( bError )
        return nullptr;

    while (poDS->hasNextTrack())
    {
        Track* poTrack = poDS->fetchNextTrack();
        if (poTrack == nullptr)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Could not read track. File probably corrupted");
            bError = true;
            return nullptr;
        }
        OGRFeature* poFeature = new OGRFeature( poFeatureDefn );
        OGRLineString* lineString = new OGRLineString ();

        for (int i = 0; i < poTrack->getNumPoints(); ++i)
        {
            const TrackPoint* psTrackPoint = poTrack->getPoint(i);
            lineString->addPoint(psTrackPoint->x,
                                 psTrackPoint->y);
        }
        if (poSRS)
            lineString->assignSpatialReference(poSRS);
        poFeature->SetField( NAME, poTrack->getName());
        poFeature->SetField( TYPE, poTrack->getType());
        poFeature->SetField( COLOR, poTrack->getColor());
        poFeature->SetFID( nNextFID++ );
        delete poTrack;

        poFeature->SetGeometryDirectly(lineString);
        if( (m_poFilterGeom == nullptr
             || FilterGeometry( poFeature->GetGeometryRef() ) )
            && (m_poAttrQuery == nullptr
                || m_poAttrQuery->Evaluate( poFeature )) )
            return poFeature;

        delete poFeature;
    }
    return nullptr;
}
Пример #8
0
static OGRErr DWGCollectBoundaryLoop( OdDbHatchPtr poHatch, int iLoop,
                                      OGRGeometryCollection *poGC )

{
    int i;

/* -------------------------------------------------------------------- */
/*      Handle simple polyline loops.                                   */
/* -------------------------------------------------------------------- */
    if( poHatch->loopTypeAt( iLoop ) & OdDbHatch::kPolyline )
    {
        DXFSmoothPolyline   oSmoothPolyline;
        OdGePoint2dArray vertices;
        OdGeDoubleArray bulges;

        poHatch->getLoopAt (iLoop, vertices, bulges);

        for (i = 0; i < (int) vertices.size(); i++)
        {
            if( i >= (int) bulges.size() )
                oSmoothPolyline.AddPoint( vertices[i].x, vertices[i].y, 0.0, 
                                          0.0 );
            else
                oSmoothPolyline.AddPoint( vertices[i].x, vertices[i].y, 0.0, 
                                          bulges[i] );
        }

        oSmoothPolyline.Close();

        OGRLineString *poLS = (OGRLineString *) oSmoothPolyline.Tesselate();
        poGC->addGeometryDirectly( poLS );

        return OGRERR_NONE;
    }

/* -------------------------------------------------------------------- */
/*      Handle an edges array.                                          */
/* -------------------------------------------------------------------- */
    EdgeArray oEdges;
    poHatch->getLoopAt( iLoop, oEdges );

    for( i = 0; i < (int) oEdges.size(); i++ )
    {
        OdGeCurve2d* poEdge = oEdges[i];

        if( poEdge->type() == OdGe::kLineSeg2d )
        {
            OGRLineString *poLS = new OGRLineString();
            OdGePoint2d oStart = poEdge->evalPoint(0.0);
            OdGePoint2d oEnd = poEdge->evalPoint(1.0);

            poLS->addPoint( oStart.x, oStart.y );
            poLS->addPoint( oEnd.x, oEnd.y );
            poGC->addGeometryDirectly( poLS );
        }
        else if( poEdge->type() == OdGe::kCircArc2d )
        {
            OdGeCircArc2d* poCircArc = (OdGeCircArc2d*) poEdge;
            OdGePoint2d oCenter = poCircArc->center();
            double dfStartAngle = poCircArc->startAng() * 180 / PI;
            double dfEndAngle = poCircArc->endAng() * 180 / PI;
            
            if( !poCircArc->isClockWise() )
            {
                dfStartAngle *= -1;
                dfEndAngle *= -1;
            }
            else if( dfStartAngle > dfEndAngle )
            {
                dfEndAngle += 360.0;
            }

            OGRLineString *poLS = (OGRLineString *) 
                OGRGeometryFactory::approximateArcAngles( 
                    oCenter.x, oCenter.y, 0.0,
                    poCircArc->radius(), poCircArc->radius(), 0.0,
                    dfStartAngle, dfEndAngle, 0.0 );

            poGC->addGeometryDirectly( poLS );
        }
        else if( poEdge->type() == OdGe::kEllipArc2d )
        {
            OdGeEllipArc2d* poArc = (OdGeEllipArc2d*) poEdge;
            OdGePoint2d oCenter = poArc->center();
            double dfRatio = poArc->minorRadius() / poArc->majorRadius();
            OdGeVector2d oMajorAxis = poArc->majorAxis();
            double dfRotation;
            double dfStartAng, dfEndAng;

            dfRotation = -1 * atan2( oMajorAxis.y, oMajorAxis.x ) * 180 / PI;

            dfStartAng = poArc->startAng()*180/PI;
            dfEndAng = poArc->endAng()*180/PI;
 
            if( !poArc->isClockWise() )
            {
                dfStartAng *= -1;
                dfEndAng *= -1;
            }
            else if( dfStartAng > dfEndAng )
            {
                dfEndAng += 360.0;
            }

            OGRLineString *poLS = (OGRLineString *) 
                OGRGeometryFactory::approximateArcAngles( 
                    oCenter.x, oCenter.y, 0.0,
                    poArc->majorRadius(), poArc->minorRadius(), dfRotation,
                    OGRDWGLayer::AngleCorrect(dfStartAng,dfRatio),
                    OGRDWGLayer::AngleCorrect(dfEndAng,dfRatio),
                    0.0 );
            poGC->addGeometryDirectly( poLS );
        }
        else
            CPLDebug( "DWG", "Unsupported edge type (%d) in hatch loop.",
                      (int) poEdge->type() );

        //case OdGe::kNurbCurve2d : dumpNurbCurveEdge(indent + 1, pEdge);    
    }

    return OGRERR_NONE;
}
Пример #9
0
int main(int argc, char *argv[])
{
    LogPolicy::GetInstance().Unmute();
    try
    {
        // enable logging
        if (argc < 3)
        {
            SimpleLogger().Write(logWARNING) << "usage:\n" << argv[0]
                                             << " <osrm> <osrm.restrictions>";
            return -1;
        }

        SimpleLogger().Write() << "Using restrictions from file: " << argv[2];
        std::ifstream restriction_ifstream(argv[2], std::ios::binary);
        const FingerPrint fingerprint_orig;
        FingerPrint fingerprint_loaded;
        restriction_ifstream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));

        // check fingerprint and warn if necessary
        if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
        {
            SimpleLogger().Write(logWARNING) << argv[2] << " was prepared with a different build. "
                                                           "Reprocess to get rid of this warning.";
        }

        if (!restriction_ifstream.good())
        {
            throw osrm::exception("Could not access <osrm-restrictions> files");
        }
        uint32_t usable_restrictions = 0;
        restriction_ifstream.read((char *)&usable_restrictions, sizeof(uint32_t));
        restriction_list.resize(usable_restrictions);

        // load restrictions
        if (usable_restrictions > 0)
        {
            restriction_ifstream.read((char *)&(restriction_list[0]),
                                      usable_restrictions * sizeof(TurnRestriction));
        }
        restriction_ifstream.close();

        std::ifstream input_stream(argv[1], std::ifstream::in | std::ifstream::binary);
        if (!input_stream.is_open())
        {
            throw osrm::exception("Cannot open osrm file");
        }

        // load graph data
        std::vector<ImportEdge> edge_list;
        const NodeID number_of_nodes = readBinaryOSRMGraphFromStream(input_stream,
                                                                     edge_list,
                                                                     bollard_node_list,
                                                                     traffic_lights_list,
                                                                     &coordinate_list,
                                                                     restriction_list);
        input_stream.close();


        BOOST_ASSERT_MSG(restriction_list.size() == usable_restrictions,
                         "size of restriction_list changed");

        SimpleLogger().Write() << restriction_list.size() << " restrictions, "
                               << bollard_node_list.size() << " bollard nodes, "
                               << traffic_lights_list.size() << " traffic lights";

        traffic_lights_list.clear();
        traffic_lights_list.shrink_to_fit();

        // Building an node-based graph
        DeallocatingVector<TarjanEdge> graph_edge_list;
        for (const NodeBasedEdge &input_edge : edge_list)
        {
            if (input_edge.source == input_edge.target)
            {
                continue;
            }

            if (input_edge.forward)
            {
                graph_edge_list.emplace_back(input_edge.source,
                                       input_edge.target,
                                       (std::max)((int)input_edge.weight, 1),
                                       input_edge.name_id);
            }
            if (input_edge.backward)
            {
                graph_edge_list.emplace_back(input_edge.target,
                                       input_edge.source,
                                       (std::max)((int)input_edge.weight, 1),
                                       input_edge.name_id);
            }
        }
        edge_list.clear();
        edge_list.shrink_to_fit();
        BOOST_ASSERT_MSG(0 == edge_list.size() && 0 == edge_list.capacity(),
                         "input edge vector not properly deallocated");

        tbb::parallel_sort(graph_edge_list.begin(), graph_edge_list.end());
        auto graph = std::make_shared<TarjanDynamicGraph>(number_of_nodes, graph_edge_list);
        edge_list.clear();
        edge_list.shrink_to_fit();

        SimpleLogger().Write() << "Starting SCC graph traversal";

        RestrictionMap restriction_map(restriction_list);
        auto tarjan = osrm::make_unique<TarjanSCC<TarjanDynamicGraph>>(graph,
                                                                       restriction_map,
                                                                       bollard_node_list);
        tarjan->run();
        SimpleLogger().Write() << "identified: " << tarjan->get_number_of_components()
                           << " many components";
        SimpleLogger().Write() << "identified " << tarjan->get_size_one_count() << " SCCs of size 1";

        // output
        TIMER_START(SCC_RUN_SETUP);

        // remove files from previous run if exist
        DeleteFileIfExists("component.dbf");
        DeleteFileIfExists("component.shx");
        DeleteFileIfExists("component.shp");

        Percent p(graph->GetNumberOfNodes());

        OGRRegisterAll();

        const char *pszDriverName = "ESRI Shapefile";
        OGRSFDriver *poDriver =
            OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
        if (nullptr == poDriver)
        {
            throw osrm::exception("ESRI Shapefile driver not available");
        }
        OGRDataSource *poDS = poDriver->CreateDataSource("component.shp", nullptr);

        if (nullptr == poDS)
        {
            throw osrm::exception("Creation of output file failed");
        }

        OGRSpatialReference *poSRS = new OGRSpatialReference();
        poSRS->importFromEPSG(4326);

        OGRLayer *poLayer = poDS->CreateLayer("component", poSRS, wkbLineString, nullptr);

        if (nullptr == poLayer)
        {
            throw osrm::exception("Layer creation failed.");
        }
        TIMER_STOP(SCC_RUN_SETUP);
        SimpleLogger().Write() << "shapefile setup took " << TIMER_MSEC(SCC_RUN_SETUP)/1000. << "s";

        uint64_t total_network_distance = 0;
        p.reinit(graph->GetNumberOfNodes());
        TIMER_START(SCC_OUTPUT);
        for (const NodeID source : osrm::irange(0u, graph->GetNumberOfNodes()))
        {
            p.printIncrement();
            for (const auto current_edge : graph->GetAdjacentEdgeRange(source))
            {
                const TarjanDynamicGraph::NodeIterator target = graph->GetTarget(current_edge);

                if (source < target || graph->EndEdges(target) == graph->FindEdge(target, source))
                {
                    total_network_distance +=
                        100 * FixedPointCoordinate::ApproximateEuclideanDistance(
                                  coordinate_list[source].lat,
                                  coordinate_list[source].lon,
                                  coordinate_list[target].lat,
                                  coordinate_list[target].lon);

                    BOOST_ASSERT(current_edge != SPECIAL_EDGEID);
                    BOOST_ASSERT(source != SPECIAL_NODEID);
                    BOOST_ASSERT(target != SPECIAL_NODEID);

                    const unsigned size_of_containing_component =
                        std::min(tarjan->get_component_size(source),
                                 tarjan->get_component_size(target));

                    // edges that end on bollard nodes may actually be in two distinct components
                    if (size_of_containing_component < 1000)
                    {
                        OGRLineString lineString;
                        lineString.addPoint(coordinate_list[source].lon / COORDINATE_PRECISION,
                                            coordinate_list[source].lat / COORDINATE_PRECISION);
                        lineString.addPoint(coordinate_list[target].lon / COORDINATE_PRECISION,
                                            coordinate_list[target].lat / COORDINATE_PRECISION);

                        OGRFeature *poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());

                        poFeature->SetGeometry(&lineString);
                        if (OGRERR_NONE != poLayer->CreateFeature(poFeature))
                        {
                            throw osrm::exception("Failed to create feature in shapefile.");
                        }
                        OGRFeature::DestroyFeature(poFeature);
                    }
                }
            }
        }
        OGRSpatialReference::DestroySpatialReference(poSRS);
        OGRDataSource::DestroyDataSource(poDS);
        TIMER_STOP(SCC_OUTPUT);
        SimpleLogger().Write() << "generating output took: " << TIMER_MSEC(SCC_OUTPUT)/1000. << "s";

        SimpleLogger().Write() << "total network distance: "
                               << (uint64_t)total_network_distance / 100 / 1000. << " km";

        SimpleLogger().Write() << "finished component analysis";
    }
    catch (const std::exception &e)
    {
        SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
    }
    return 0;
}
Пример #10
0
void ILI1Reader::ReadGeom( char **stgeom, int geomIdx, OGRwkbGeometryType eType,
                           OGRFeature *feature ) {
#ifdef DEBUG_VERBOSE
    CPLDebug( "OGR_ILI",
              "ILI1Reader::ReadGeom geomIdx: %d OGRGeometryType: %s",
              geomIdx, OGRGeometryTypeToName(eType) );
#endif
    if (eType == wkbNone)
    {
      CPLError( CE_Warning, CPLE_AppDefined,
                "Calling ILI1Reader::ReadGeom with wkbNone" );
    }

    // Initialize geometry.

    OGRCompoundCurve *ogrCurve = new OGRCompoundCurve();
    OGRCurvePolygon *ogrPoly = NULL; //current polygon
    OGRMultiCurve *ogrMultiLine = NULL; //current multi line

    if (eType == wkbMultiCurve || eType == wkbMultiLineString)
    {
      ogrMultiLine = new OGRMultiCurve();
    }
    else if (eType == wkbPolygon || eType == wkbCurvePolygon)
    {
      ogrPoly = new OGRCurvePolygon();
    }

    OGRPoint ogrPoint; // Current point.
    ogrPoint.setX(CPLAtof(stgeom[1])); ogrPoint.setY(CPLAtof(stgeom[2]));

    OGRLineString *ogrLine = new OGRLineString();
    ogrLine->addPoint(&ogrPoint);

    // Parse geometry.

    char **tokens = NULL;
    bool end = false;
    OGRCircularString *arc = NULL; //current arc

    while (!end && (tokens = ReadParseLine()) != NULL)
    {
      const char *firsttok = CSLGetField(tokens, 0);
      if( firsttok == NULL )
      {
          // do nothing
      }
      else if (EQUAL(firsttok, "LIPT") && CSLCount(tokens) >= 3)
      {
        ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2]));
        if (arc) {
          arc->addPoint(&ogrPoint);
          OGRErr error =  ogrCurve->addCurveDirectly(arc);
          if (error != OGRERR_NONE) {
            char* pszJSon = arc->exportToJson();
            CPLError(CE_Warning, CPLE_AppDefined, "Could not add geometry: %s",
                     pszJSon ? pszJSon : "(null)" );
            CPLFree(pszJSon);
            delete arc;
          }
          arc = NULL;
        }
        ogrLine->addPoint(&ogrPoint);
      }
      else if (EQUAL(firsttok, "ARCP") && CSLCount(tokens) >= 3)
      {
        //Finish line and start arc
        if (ogrLine->getNumPoints() > 1) {
          OGRErr error = ogrCurve->addCurveDirectly(ogrLine);
          if (error != OGRERR_NONE) {
            char* pszJSon = ogrLine->exportToJson();
            CPLError(CE_Warning, CPLE_AppDefined, "Could not add geometry: %s",
                     pszJSon ? pszJSon : "(null)" );
            CPLFree(pszJSon);
            delete ogrLine;
          }
          ogrLine = new OGRLineString();
        } else {
          ogrLine->empty();
        }
        delete arc;
        arc = new OGRCircularString();
        arc->addPoint(&ogrPoint);
        ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2]));
        arc->addPoint(&ogrPoint);
      }
      else if (EQUAL(firsttok, "ELIN"))
      {
        if (ogrLine->getNumPoints() > 1) { // Ignore single LIPT after ARCP
          OGRErr error = ogrCurve->addCurveDirectly(ogrLine);
          if (error != OGRERR_NONE) {
            char* pszJSon = ogrLine->exportToJson();
            CPLError(CE_Warning, CPLE_AppDefined, "Could not add geometry: %s",
                     pszJSon ? pszJSon : "(null)" );
            CPLFree(pszJSon);
            delete ogrLine;
          }
          ogrLine = NULL;
        }
        if (!ogrCurve->IsEmpty()) {
          if (ogrMultiLine)
          {
            OGRErr error = ogrMultiLine->addGeometryDirectly(ogrCurve);
            if (error != OGRERR_NONE) {
              char* pszJSon = ogrCurve->exportToJson();
              CPLError(CE_Warning, CPLE_AppDefined, "Could not add geometry: %s",
                       pszJSon ? pszJSon : "(null)" );
              CPLFree(pszJSon);
              delete ogrCurve;
            }
            ogrCurve = NULL;
          }
          if (ogrPoly)
          {
            OGRErr error = ogrPoly->addRingDirectly(ogrCurve);
            if (error != OGRERR_NONE) {
              char* pszJSon = ogrCurve->exportToJson();
              CPLError(CE_Warning, CPLE_AppDefined, "Could not add geometry: %s",
                       pszJSon ? pszJSon : "(null)" );
              CPLFree(pszJSon);
              delete ogrCurve;
            }
            ogrCurve = NULL;
          }
        }
        end = true;
      }
      else if (EQUAL(firsttok, "EEDG"))
      {
        end = true;
      }
      else if (EQUAL(firsttok, "LATT"))
      {
        //Line Attributes (ignored)
      }
      else if (EQUAL(firsttok, "EFLA"))
      {
        end = true;
      }
      else if (EQUAL(firsttok, "ETAB"))
      {
        end = true;
      }
      else
      {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Unexpected token: %s", firsttok );
      }

      CSLDestroy(tokens);
    }
    delete arc;

    delete ogrLine;

    //Set feature geometry
    if (eType == wkbMultiCurve)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine);
      delete ogrCurve;
    }
    else if (eType == wkbMultiLineString)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine->getLinearGeometry());
      delete ogrMultiLine;
      delete ogrCurve;
    }
    else if (eType == wkbCurvePolygon)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrPoly);
      delete ogrCurve;
    }
    else if (eType == wkbPolygon)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrPoly->getLinearGeometry());
      delete ogrPoly;
      delete ogrCurve;
    }
    else
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrCurve);
    }
}
Пример #11
0
	bool Shape::save(const std::string& filename) {
		if (shapeType == -1) {
			std::cout << "Shape type is not set." << std::endl;
			return false;
		}

		if (shapeObjects.size() == 0) {
			std::cout << "No shape exists." << std::endl;
			return false;
		}

		const char *pszDriverName = "ESRI Shapefile";
		GDALDriver *poDriver;
		GDALAllRegister();

		poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName);
		if (poDriver == NULL) {
			printf("%s driver not available.\n", pszDriverName);
			return false;
		}

		GDALDataset *poDS;
		poDS = poDriver->Create(filename.c_str(), 0, 0, 0, GDT_Unknown, NULL);
		if (poDS == NULL) {
			printf("Creation of output file failed.\n");
			return false;
		}

		OGRLayer *poLayer;
		if (shapeType == wkbPoint) {
			poLayer = poDS->CreateLayer("point_out", NULL, wkbPoint, NULL);
		}
		else if (shapeType == wkbLineString) {
			poLayer = poDS->CreateLayer("point_out", NULL, wkbLineString, NULL);
		}
		else if (shapeType == wkbPolygon) {
			poLayer = poDS->CreateLayer("point_out", NULL, wkbPolygon, NULL);
		}
		if (poLayer == NULL) {
			printf("Layer creation failed.\n");
			return false;
		}

		for (auto it = shapeObjects[0].attributes.begin(); it != shapeObjects[0].attributes.end(); ++it) {
			OGRFieldDefn oField(it->first.c_str(), static_cast<OGRFieldType>(it->second.type));
			if (it->second.type == OFTString) {
				oField.SetWidth(it->second.stringValue().size());
			}
			if (poLayer->CreateField(&oField) != OGRERR_NONE) {
				printf("Creating Name field failed.\n");
				return false;
			}
		}
				
		for (int i = 0; i < shapeObjects.size(); ++i) {
			if (shapeObjects[i].parts.size() == 0) continue;
			
			OGRFeature *poFeature;
			poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());

			// 属性をセット
			for (auto it = shapeObjects[i].attributes.begin(); it != shapeObjects[i].attributes.end(); ++it) {
				poFeature->SetField(it->first.c_str(), it->second.stringValue().c_str());
			}

			// ジオメトリ情報をセット
			if (shapeType == wkbPoint) {
				OGRPoint point;
				point.setX(shapeObjects[i].parts[0].points[0].x);
				point.setY(shapeObjects[i].parts[0].points[0].y);
				point.setZ(shapeObjects[i].parts[0].points[0].z);
				poFeature->SetGeometry(&point);
			}
			else if (shapeType == wkbLineString) {
				OGRLineString lineString;
				for (int k = 0; k < shapeObjects[i].parts[0].points.size(); ++k) {
					lineString.addPoint(shapeObjects[i].parts[0].points[k].x, shapeObjects[i].parts[0].points[k].y, shapeObjects[i].parts[0].points[k].z);
				}
				poFeature->SetGeometry(&lineString);
			}
			else if (shapeType == wkbPolygon) {
				OGRPolygon polygon;
				for (int j = 0; j < shapeObjects[i].parts.size(); ++j) {
					OGRLinearRing linearRing;
					for (int k = 0; k < shapeObjects[i].parts[j].points.size(); ++k) {
						linearRing.addPoint(shapeObjects[i].parts[j].points[k].x, shapeObjects[i].parts[j].points[k].y, shapeObjects[i].parts[j].points[k].z);
					}
					polygon.addRing(&linearRing);
				}
				poFeature->SetGeometry(&polygon);
			}
			
			if (poLayer->CreateFeature(poFeature) != OGRERR_NONE) {
				printf("Failed to create feature in shapefile.\n");
				return false;
			}
			OGRFeature::DestroyFeature(poFeature);
		}

		GDALClose(poDS);

		return true;
	}
Пример #12
0
OGRLineString *getLineString(DOMElement *elem, int bAsLinearRing) {
  // elem -> POLYLINE
  OGRLineString *ls;
  if (bAsLinearRing)
      ls = new OGRLinearRing();
  else
      ls = new OGRLineString();

  DOMElement *lineElem = (DOMElement *)elem->getFirstChild();
  while (lineElem != NULL) {
    char* pszTagName = XMLString::transcode(lineElem->getTagName());
    if (cmpStr(ILI2_COORD, pszTagName) == 0)
    {
      OGRPoint* poPoint = getPoint(lineElem);
      ls->addPoint(poPoint);
      delete poPoint;
    }
    else if (cmpStr(ILI2_ARC, pszTagName) == 0) {
      // end point
      OGRPoint *ptEnd = new OGRPoint();
      // point on the arc
      OGRPoint *ptOnArc = new OGRPoint();
      // radius
      double radius = 0;

      DOMElement *arcElem = (DOMElement *)lineElem->getFirstChild();
      while (arcElem != NULL) {
        char* pszTagName = XMLString::transcode(arcElem->getTagName());
        char* pszObjValue = getObjValue(arcElem);
        if (cmpStr("C1", pszTagName) == 0)
          ptEnd->setX(atof(pszObjValue));
        else if (cmpStr("C2", pszTagName) == 0)
          ptEnd->setY(atof(pszObjValue));
        else if (cmpStr("C3", pszTagName) == 0)
          ptEnd->setZ(atof(pszObjValue));
        else if (cmpStr("A1", pszTagName) == 0)
          ptOnArc->setX(atof(pszObjValue));
        else if (cmpStr("A2", pszTagName) == 0)
          ptOnArc->setY(atof(pszObjValue));
        else if (cmpStr("A3", pszTagName) == 0)
          ptOnArc->setZ(atof(pszObjValue));
        else if (cmpStr("R", pszTagName) == 0)
          radius = atof(pszObjValue);
        CPLFree(pszObjValue);
        XMLString::release(&pszTagName);

        arcElem = (DOMElement *)arcElem->getNextSibling();
      }

      ptEnd->flattenTo2D();
      ptOnArc->flattenTo2D();
      OGRPoint *ptStart = getPoint((DOMElement *)lineElem->getPreviousSibling()); // COORD or ARC
      interpolateArc(ls, ptStart, ptOnArc, ptEnd, PI/180);

      delete ptStart;
      delete ptEnd;
      delete ptOnArc;
    } /* else { // FIXME StructureValue in Polyline not yet supported
    } */
    XMLString::release(&pszTagName);

    lineElem = (DOMElement *)lineElem->getNextSibling();
  }

  return ls;
}
Пример #13
0
OGRErr OGRDXFLayer::CollectBoundaryPath( OGRGeometryCollection *poGC,
    const double dfElevation )

{
    char szLineBuf[257];

/* -------------------------------------------------------------------- */
/*      Read the boundary path type.                                    */
/* -------------------------------------------------------------------- */
    int nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 92 )
    {
        DXF_LAYER_READER_ERROR();
        return OGRERR_FAILURE;
    }

    const int nBoundaryPathType = atoi(szLineBuf);

/* ==================================================================== */
/*      Handle polyline loops.                                          */
/* ==================================================================== */
    if( nBoundaryPathType & 0x02 )
        return CollectPolylinePath( poGC, dfElevation );

/* ==================================================================== */
/*      Handle non-polyline loops.                                      */
/* ==================================================================== */

/* -------------------------------------------------------------------- */
/*      Read number of edges.                                           */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 93 )
    {
        DXF_LAYER_READER_ERROR();
        return OGRERR_FAILURE;
    }

    const int nEdgeCount = atoi(szLineBuf);

/* -------------------------------------------------------------------- */
/*      Loop reading edges.                                             */
/* -------------------------------------------------------------------- */
    for( int iEdge = 0; iEdge < nEdgeCount; iEdge++ )
    {
/* -------------------------------------------------------------------- */
/*      Read the edge type.                                             */
/* -------------------------------------------------------------------- */
        const int ET_LINE = 1;
        const int ET_CIRCULAR_ARC = 2;
        const int ET_ELLIPTIC_ARC = 3;
        const int ET_SPLINE = 4;

        nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
        if( nCode != 72 )
        {
            DXF_LAYER_READER_ERROR();
            return OGRERR_FAILURE;
        }

        int nEdgeType = atoi(szLineBuf);

/* -------------------------------------------------------------------- */
/*      Process a line edge.                                            */
/* -------------------------------------------------------------------- */
        if( nEdgeType == ET_LINE )
        {
            double dfStartX = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 10 )
                dfStartX = CPLAtof(szLineBuf);
            else
                break;

            double dfStartY = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 20 )
                dfStartY = CPLAtof(szLineBuf);
            else
                break;

            double dfEndX = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 11 )
                dfEndX = CPLAtof(szLineBuf);
            else
                break;

            double dfEndY = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 21 )
                dfEndY = CPLAtof(szLineBuf);
            else
                break;

            OGRLineString *poLS = new OGRLineString();

            poLS->addPoint( dfStartX, dfStartY, dfElevation );
            poLS->addPoint( dfEndX, dfEndY, dfElevation );

            poGC->addGeometryDirectly( poLS );
        }
/* -------------------------------------------------------------------- */
/*      Process a circular arc.                                         */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_CIRCULAR_ARC )
        {
            double dfCenterX = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 10 )
                dfCenterX = CPLAtof(szLineBuf);
            else
                break;

            double dfCenterY = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 20 )
                dfCenterY = CPLAtof(szLineBuf);
            else
                break;

            double dfRadius = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 40 )
                dfRadius = CPLAtof(szLineBuf);
            else
                break;

            double dfStartAngle = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 50 )
                dfStartAngle = CPLAtof(szLineBuf);
            else
                break;

            double dfEndAngle = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 51 )
                dfEndAngle = CPLAtof(szLineBuf);
            else
                break;

            bool bCounterClockwise = false;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 73 )
                bCounterClockwise = atoi(szLineBuf) != 0;
            else if (nCode >= 0)
                poDS->UnreadValue();
            else
                break;

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;
            if( bCounterClockwise )
            {
                dfStartAngle *= -1;
                dfEndAngle *= -1;
            }

            if( fabs(dfEndAngle - dfStartAngle) <= 361.0 )
            {
                OGRGeometry *poArc = OGRGeometryFactory::approximateArcAngles(
                    dfCenterX, dfCenterY, dfElevation,
                    dfRadius, dfRadius, 0.0,
                    dfStartAngle, dfEndAngle, 0.0 );

                // If the input was 2D, we assume we want to keep it that way
                if( dfElevation == 0.0 )
                    poArc->flattenTo2D();

                poGC->addGeometryDirectly( poArc );
            }
            else
            {
                // TODO: emit error ?
            }
        }

/* -------------------------------------------------------------------- */
/*      Process an elliptical arc.                                      */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_ELLIPTIC_ARC )
        {
            double dfCenterX = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 10 )
                dfCenterX = CPLAtof(szLineBuf);
            else
                break;

            double dfCenterY = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 20 )
                dfCenterY = CPLAtof(szLineBuf);
            else
                break;

            double dfMajorX = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 11 )
                dfMajorX = CPLAtof(szLineBuf);
            else
                break;

            double dfMajorY = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 21 )
                dfMajorY = CPLAtof(szLineBuf);
            else
                break;

            double dfRatio = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 40 )
                dfRatio = CPLAtof(szLineBuf);
            if( dfRatio == 0.0 )
                break;

            double dfStartAngle = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 50 )
                dfStartAngle = CPLAtof(szLineBuf);
            else
                break;

            double dfEndAngle = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 51 )
                dfEndAngle = CPLAtof(szLineBuf);
            else
                break;

            bool bCounterClockwise = false;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 73 )
                bCounterClockwise = atoi(szLineBuf) != 0;
            else if (nCode >= 0)
                poDS->UnreadValue();
            else
                break;

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;
            if( bCounterClockwise )
            {
                dfStartAngle *= -1;
                dfEndAngle *= -1;
            }

            const double dfMajorRadius =
                sqrt( dfMajorX * dfMajorX + dfMajorY * dfMajorY );
            const double dfMinorRadius = dfMajorRadius * dfRatio;

            const double dfRotation =
                -1 * atan2( dfMajorY, dfMajorX ) * 180 / M_PI;

            // The start and end angles are stored as circular angles. However,
            // approximateArcAngles is expecting elliptical angles (what AutoCAD
            // calls "parameters"), so let's transform them.
            dfStartAngle = 180.0 * floor ( ( dfStartAngle + 90 ) / 180 ) +
                    atan( ( 1.0 / dfRatio ) * tan( dfStartAngle * M_PI / 180 ) ) * 180 / M_PI;
            dfEndAngle = 180.0 * floor ( ( dfEndAngle + 90 ) / 180 ) +
                    atan( ( 1.0 / dfRatio ) * tan( dfEndAngle * M_PI / 180 ) ) * 180 / M_PI;

            if( fabs(dfEndAngle - dfStartAngle) <= 361.0 )
            {
                OGRGeometry *poArc = OGRGeometryFactory::approximateArcAngles(
                    dfCenterX, dfCenterY, dfElevation,
                    dfMajorRadius, dfMinorRadius, dfRotation,
                    dfStartAngle, dfEndAngle, 0.0 );

                // If the input was 2D, we assume we want to keep it that way
                if( dfElevation == 0.0 )
                    poArc->flattenTo2D();

                poGC->addGeometryDirectly( poArc );
            }
            else
            {
                // TODO: emit error ?
            }
        }

/* -------------------------------------------------------------------- */
/*      Process an elliptical arc.                                      */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_SPLINE )
        {
            int nDegree = 3;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 94 )
                nDegree = atoi(szLineBuf);
            else
                break;

            // Skip a few things we don't care about
            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) != 73 )
                break;
            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) != 74 )
                break;

            int nKnots = 0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 95 )
                nKnots = atoi(szLineBuf);
            else
                break;

            int nControlPoints = 0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 96 )
                nControlPoints = atoi(szLineBuf);
            else
                break;

            std::vector<double> adfKnots( 1, 0.0 );

            nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf));
            if( nCode != 40 )
                break;

            while( nCode == 40 )
            {
                adfKnots.push_back( CPLAtof(szLineBuf) );
                nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf));
            }

            std::vector<double> adfControlPoints( 1, 0.0 );
            std::vector<double> adfWeights( 1, 0.0 );

            if( nCode != 10 )
                break;

            while( nCode == 10 )
            {
                adfControlPoints.push_back( CPLAtof(szLineBuf) );

                if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 20 )
                {
                    adfControlPoints.push_back( CPLAtof(szLineBuf) );
                }
                else
                    break;

                adfControlPoints.push_back( 0.0 ); // Z coordinate

                // 42 (weights) are optional
                if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 42 )
                {
                    adfWeights.push_back( CPLAtof(szLineBuf) );
                    nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf));
                }
            }

            // Skip past the number of fit points
            if( nCode != 97 )
                break;

            // Eat the rest of this section, if present, until the next
            // boundary segment (72) or the conclusion of the boundary data (97)
            nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf));
            while( nCode > 0 && nCode != 72 && nCode != 97 )
                nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf));
            if( nCode > 0 )
                poDS->UnreadValue();

            OGRLineString *poLS = InsertSplineWithChecks( nDegree,
                adfControlPoints, nControlPoints, adfKnots, nKnots,
                adfWeights );

            if( !poLS )
            {
                DXF_LAYER_READER_ERROR();
                return OGRERR_FAILURE;
            }

            poGC->addGeometryDirectly( poLS );
        }

        else
        {
            CPLDebug( "DXF", "Unsupported HATCH boundary line type:%d",
                      nEdgeType );
            return OGRERR_UNSUPPORTED_OPERATION;
        }
    }

    if( nCode < 0 )
    {
        DXF_LAYER_READER_ERROR();
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Skip through source boundary objects if present.                */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 97 )
    {
        if (nCode < 0)
            return OGRERR_FAILURE;
        poDS->UnreadValue();
    }
    else
    {
        int iObj, nObjCount = atoi(szLineBuf);

        for( iObj = 0; iObj < nObjCount; iObj++ )
        {
            if (poDS->ReadValue( szLineBuf, sizeof(szLineBuf) ) < 0)
                return OGRERR_FAILURE;
        }
    }

    return OGRERR_NONE;
}
Пример #14
0
/*!
  \brief Load geometry (linestring SBP layer)

  \return number of invalid features
*/
int VFKDataBlockDB::LoadGeometryLineStringSBP()
{
    int       nInvalid, nGeometries, rowId, iIdx;
    CPLString szFType, szFTypeLine;

    GUIntBig id, ipcb;
    bool     bValid;

    std::vector<int> rowIdFeat;
    CPLString     osSQL;

    VFKReaderDB    *poReader;
    VFKDataBlockDB *poDataBlockPoints;
    VFKFeatureDB   *poFeature, *poPoint, *poLine;

    OGRLineString oOGRLine;

    nInvalid  = nGeometries = 0;
    poReader  = (VFKReaderDB*) m_poReader;
    poLine    = NULL;

    poDataBlockPoints = (VFKDataBlockDB *) m_poReader->GetDataBlock("SOBR");
    if (NULL == poDataBlockPoints) {
        CPLError(CE_Failure, CPLE_FileIO,
                 "Data block %s not found.\n", m_pszName);
        return nInvalid;
    }

    poDataBlockPoints->LoadGeometry();

    if (LoadGeometryFromDB()) /* try to load geometry from DB */
	return 0;

    osSQL.Printf("UPDATE %s SET %s = -1", m_pszName, FID_COLUMN);
    poReader->ExecuteSQL(osSQL.c_str());
    bValid = TRUE;
    iIdx = 0;
    for (int i = 0; i < 2; i++) {
	/* first collect linestrings related to HP, OB or DPM
	   then collect rest of linestrings */
        if (i == 0)
            osSQL.Printf("SELECT BP_ID,PORADOVE_CISLO_BODU,PARAMETRY_SPOJENI,_rowid_ FROM '%s' WHERE "
                         "HP_ID IS NOT NULL OR OB_ID IS NOT NULL OR DPM_ID IS NOT NULL "
                         "ORDER BY HP_ID,OB_ID,DPM_ID,PORADOVE_CISLO_BODU", m_pszName);
        else
            osSQL.Printf("SELECT BP_ID,PORADOVE_CISLO_BODU,PARAMETRY_SPOJENI,_rowid_ FROM '%s' WHERE "
                         "OB_ID IS NULL AND HP_ID IS NULL AND DPM_ID IS NULL "
                         "ORDER BY ID,PORADOVE_CISLO_BODU", m_pszName);

	if (poReader->IsSpatial())
	    poReader->ExecuteSQL("BEGIN");

        std::vector<VFKDbValue> record;
        record.push_back(VFKDbValue(DT_BIGINT));
        record.push_back(VFKDbValue(DT_BIGINT));
        record.push_back(VFKDbValue(DT_TEXT));
        record.push_back(VFKDbValue(DT_INT));
        poReader->PrepareStatement(osSQL.c_str());
        while(poReader->ExecuteSQL(record) == OGRERR_NONE) {
            // read values
            id    = (GIntBig) record[0];
            ipcb  = (GIntBig) record[1];
            szFType = (CPLString) record[2];
            rowId = (int) record[3];

            if (ipcb == 1) {
                poFeature = (VFKFeatureDB *) GetFeatureByIndex(iIdx);
                if( poFeature == NULL )
                {
                    CPLError(CE_Failure, CPLE_AppDefined, "Cannot retrieve feature %d", iIdx);
                    break;
                }
                poFeature->SetRowId(rowId);

                /* set geometry & reset */
                if (poLine && !SetGeometryLineString(poLine, &oOGRLine,
                                                     bValid, szFTypeLine, rowIdFeat, nGeometries)) {
                    nInvalid++;
                }

		bValid = TRUE;
                poLine = poFeature;
                szFTypeLine = szFType;
                iIdx++;
            }

            poPoint = (VFKFeatureDB *) poDataBlockPoints->GetFeature("ID", id);
	    if (poPoint) {
		OGRPoint *pt = (OGRPoint *) poPoint->GetGeometry();
		if (pt) {
		    oOGRLine.addPoint(pt);
		}
		else {
		    CPLDebug("OGR-VFK",
			     "Geometry (point ID = " CPL_FRMT_GUIB ") not valid", id);
		    bValid = FALSE;
		}
	    }
	    else {
                CPLDebug("OGR-VFK",
                         "Point ID = " CPL_FRMT_GUIB " not found (rowid = %d)",
                         id, rowId);
		bValid = FALSE;
            }

	    /* add vertex to the linestring */
	    rowIdFeat.push_back(rowId);
        }

        /* add last line */
        if (poLine && !SetGeometryLineString(poLine, &oOGRLine,
                                             bValid, szFType.c_str(), rowIdFeat, nGeometries)) {
            nInvalid++;
        }
	poLine = NULL;

	if (poReader->IsSpatial())
	    poReader->ExecuteSQL("COMMIT");
    }

    /* update number of geometries in VFK_DB_TABLE table */
    UpdateVfkBlocks(nGeometries);

    return nInvalid;
}
Пример #15
0
GDAL_GCP * PrepareGCP(const CPLString& sFileName, OGRPoint *pt1, OGRPoint *pt2, OGRPoint *pt3, OGRPoint *pt4, OGRPoint *ptCenter, const OGRSpatialReference &oDstOGRSpatialReference, const int nRasterSizeX, const int nRasterSizeY, int &nGCPCount, OGREnvelope &DstEnv)
{
    // to meters
    double dfFocusM = dfFocus / 100;
    double dfFilmHalfHeightM = dfFilmHeight / 200;
    double dfRatio = dfFilmHalfHeightM / dfFocusM;

    //create center point and line of scene
    OGRPoint ptShortSideBeg = GetCenterOfLine(pt1, pt4);
    OGRPoint ptShortSideEnd = GetCenterOfLine(pt2, pt3);

    OGRLineString lnTmp;
    lnTmp.addPoint(&ptShortSideBeg);
    lnTmp.addPoint(&ptShortSideEnd);

    lnTmp.Value(lnTmp.Project(pt1), &ptShortSideBeg);
    lnTmp.Value(lnTmp.Project(pt2), &ptShortSideEnd);

    double dfDist1 = pt1->Distance(pt2);
    double dfDist2 = pt2->Distance(pt3);
    double dfDist3 = pt3->Distance(pt4);
    double dfDist4 = pt4->Distance(pt1);
    double dfHalfWidth = (dfDist2 + dfDist4) / 4;
    double dfHalfHeight = (dfDist1 + dfDist3) / 4;

    double dfAltitudeAtSide = (dfHalfWidth * dfFocusM) / dfFilmHalfHeightM;
    double dfAltitudeAtSceneCenter = sqrt( dfAltitudeAtSide * dfAltitudeAtSide - dfHalfHeight * dfHalfHeight);
    double dfAltitude = dfAltitudeAtSceneCenter * cos(dfMountAngleRad); // 145 - 220 km
    double dfDistCenter = dfAltitudeAtSceneCenter * sin(dfMountAngleRad);

    OGRLineString lnCenterLeft;
    lnCenterLeft.addPoint(&ptShortSideBeg);
    lnCenterLeft.addPoint(ptCenter);
    OGRPoint ptSatCenter = GetTangetPoint(lnCenterLeft, dfDistCenter);

    std::vector<OGRPoint> aPt1, aPt2;
    int nTotalGCPCount = ((SEGMENT_STEPS + 1) * 2);
    GDAL_GCP *paGSPs = (GDAL_GCP *) CPLMalloc (nTotalGCPCount * sizeof(GDAL_GCP));
    GDALInitGCPs(nTotalGCPCount, paGSPs);

    double dfImageStepLen = double(nRasterSizeX) / SEGMENT_STEPS;
    double dfImageCenterX = 0;

    OGRLineString lnCenter;
    lnCenter.addPoint(&ptShortSideBeg);
    lnCenter.addPoint(ptCenter);
    lnCenter.addPoint(&ptShortSideEnd);

    double dfCenterLineLen = lnCenter.get_Length();
    double dfStepLen = dfCenterLineLen / SEGMENT_STEPS;
    double dfCenterLineHalfLen = dfCenterLineLen / 2;

    for(double i = 0; i <= dfCenterLineLen; i += dfStepLen)
    {
        OGRPoint ptTmp;
        lnCenter.Value(i, &ptTmp);

        double dfDist = fabs(dfCenterLineHalfLen - i);

        double dfWidthTmp = GetWidthForHeight(dfAltitudeAtSceneCenter, dfDist, dfRatio);

        OGRLineString lnTmpLine;
        lnTmpLine.addPoint(ptCenter);
        lnTmpLine.addPoint(&ptTmp);

        int direction = 1;
        if(dfCenterLineHalfLen < i)
            direction = -1;

        OGRPoint ptUp = GetTangetPoint(lnTmpLine, dfWidthTmp * direction);
        OGRPoint ptDown = GetTangetPoint(lnTmpLine, -dfWidthTmp * direction);

        //OGRPoint ptUp = GetValue(dfWidthTmp, lnTmpLine);
        //OGRPoint ptDown = GetValue(-dfWidthTmp, lnTmpLine);

        aPt1.push_back(ptUp);
        aPt2.push_back(ptDown);

        paGSPs[nGCPCount].dfGCPLine = 0;
        paGSPs[nGCPCount].dfGCPPixel = dfImageCenterX;
        paGSPs[nGCPCount].dfGCPX = ptDown.getX();
        paGSPs[nGCPCount].dfGCPY = ptDown.getY();
        paGSPs[nGCPCount].dfGCPZ = dfMeanHeight;
        paGSPs[nGCPCount].pszId = CPLStrdup(CPLSPrintf("pt%d", nGCPCount));
        nGCPCount++;

        paGSPs[nGCPCount].dfGCPLine = nRasterSizeY;
        paGSPs[nGCPCount].dfGCPPixel = dfImageCenterX;
        paGSPs[nGCPCount].dfGCPX = ptUp.getX();
        paGSPs[nGCPCount].dfGCPY = ptUp.getY();
        paGSPs[nGCPCount].dfGCPZ = dfMeanHeight;
        paGSPs[nGCPCount].pszId = CPLStrdup(CPLSPrintf("pt%d", nGCPCount));
        nGCPCount++;

        dfImageCenterX += dfImageStepLen;
    }

    // add points to polygon
    OGRLinearRing Ring;
    for(int i = 0; i < aPt1.size(); ++i)
        Ring.addPoint(aPt1[i].getX(), aPt1[i].getY());

    for(int i = aPt2.size() - 1; i >= 0; --i)
        Ring.addPoint(aPt2[i].getX(), aPt2[i].getY());

    Ring.closeRings();

    OGRPolygon Rgn;
    Rgn.addRingDirectly((OGRCurve*)Ring.clone());
    Rgn.assignSpatialReference(oDstOGRSpatialReference.Clone());
    Rgn.flattenTo2D();

    Rgn.getEnvelope(&DstEnv);

    SaveGeometry(CPLResetExtension(sFileName, "shp"), Rgn, oDstOGRSpatialReference);

    return paGSPs;
}
Пример #16
0
OGRGeometry * cvct2gdal::CVCT2GDALGeometry ( VCTGeometry & oVCTGeometry )
{
	OGRGeometry * poOGRGeometry = NULL;
	Geometry * poGeometry = NULL;

	if ( oVCTGeometry.geotype == GT_POINT )
	{
		PointParser oParser ( poVCTFile, poVCTDataSource );
		poGeometry = oParser.Parse ( oVCTGeometry );
		Geometry & cGeometry = *poGeometry;
		OGRGeometry * poPoint = new OGRPoint (cGeometry[0]->operator[](0).X,
		                                      cGeometry[0]->operator[](0).Y);
		poOGRGeometry = poPoint;
	}

	else if ( oVCTGeometry.geotype == GT_LINE )
	{
		LineParser  oParser ( poVCTFile, poVCTDataSource );
		poGeometry = oParser.Parse ( oVCTGeometry );
		Geometry & cGeometry = *poGeometry;
		OGRLineString * poLine = new OGRLineString();

		for ( auto iter = cGeometry[0]->begin();
		        iter != cGeometry[0]->end(); ++iter )
		{
			poLine->addPoint ( iter->X, iter->Y );
		}

		poOGRGeometry = poLine;
	}

	else if ( oVCTGeometry.geotype == GT_POLYGON )
	{
		PolyParser oParser ( poVCTFile, poVCTDataSource );
		poGeometry = oParser.Parse ( oVCTGeometry );
		Geometry & cGeometry = *poGeometry;
		int nParts = cGeometry.size();

		if (nParts == 1)
		{
			OGRPolygon * poOGRPoly = NULL;
			OGRLinearRing * poRing = NULL;
			poOGRGeometry = poOGRPoly = new OGRPolygon();
			poRing = CreateLinearRing(*cGeometry[0]);
			poOGRPoly->addRingDirectly(poRing);
		}

		else
		{
			OGRPolygon ** tabPolygons = new OGRPolygon*[nParts];

			for ( int iRing = 0; iRing != nParts; ++iRing )
			{
				tabPolygons[iRing] = new OGRPolygon();
				tabPolygons[iRing]->addRingDirectly ( CreateLinearRing ( *cGeometry[iRing] ) );
			}

			int isValidGeometry;
			const char * papszOptions[] = { "METHOD=ONLY_CCW", NULL };
			poOGRGeometry = OGRGeometryFactory::organizePolygons (
			                    ( OGRGeometry ** ) tabPolygons, nParts, &isValidGeometry, papszOptions );

			delete[] tabPolygons;
		}
	}

	DestroyGeometry(poGeometry);

	return poOGRGeometry;
}
Пример #17
0
OGRFeature *OGRARCGENLayer::GetNextRawFeature()
{
    if (bEOF)
        return nullptr;

    OGRwkbGeometryType eType = poFeatureDefn->GetGeomType();

    if (wkbFlatten(eType) == wkbPoint)
    {
        while( true )
        {
            const char* pszLine = CPLReadLine2L(fp,256,nullptr);
            if (pszLine == nullptr || EQUAL(pszLine, "END"))
            {
                bEOF = true;
                return nullptr;
            }
            char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 );
            int nTokens = CSLCount(papszTokens);
            if (nTokens == 3 || nTokens == 4)
            {
                OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
                poFeature->SetFID(nNextFID ++);
                poFeature->SetField(0, papszTokens[0]);
                if (nTokens == 3)
                    poFeature->SetGeometryDirectly(
                        new OGRPoint(CPLAtof(papszTokens[1]),
                                     CPLAtof(papszTokens[2])));
                else
                    poFeature->SetGeometryDirectly(
                        new OGRPoint(CPLAtof(papszTokens[1]),
                                     CPLAtof(papszTokens[2]),
                                     CPLAtof(papszTokens[3])));
                CSLDestroy(papszTokens);
                return poFeature;
            }

            CSLDestroy(papszTokens);
        }
    }

    CPLString osID;
    const bool bIsPoly = (wkbFlatten(eType) == wkbPolygon);
    OGRwkbGeometryType eRingType = (bIsPoly) ? wkbLinearRing : wkbLineString;
    OGRLineString* poLS =
        OGRGeometryFactory::createGeometry(eRingType)->toLineString();
    while( true )
    {
        const char* pszLine = CPLReadLine2L(fp,256,nullptr);
        if (pszLine == nullptr)
            break;

        if (EQUAL(pszLine, "END"))
        {
            if (osID.empty())
                break;

            OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
            poFeature->SetFID(nNextFID ++);
            poFeature->SetField(0, osID.c_str());
            if( bIsPoly )
            {
                OGRPolygon* poPoly = new OGRPolygon();
                poPoly->addRingDirectly(poLS->toLinearRing());
                poFeature->SetGeometryDirectly(poPoly);
            }
            else
                poFeature->SetGeometryDirectly(poLS);
            return poFeature;
        }

        char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 );
        int nTokens = CSLCount(papszTokens);
        if (osID.empty())
        {
            if (nTokens >= 1)
                osID = papszTokens[0];
            else
            {
                CSLDestroy(papszTokens);
                break;
            }
        }
        else
        {
            if (nTokens == 2)
            {
                poLS->addPoint(CPLAtof(papszTokens[0]),
                               CPLAtof(papszTokens[1]));
            }
            else if (nTokens == 3)
            {
                poLS->addPoint(CPLAtof(papszTokens[0]),
                               CPLAtof(papszTokens[1]),
                               CPLAtof(papszTokens[2]));
            }
            else
            {
                CSLDestroy(papszTokens);
                break;
            }
        }
        CSLDestroy(papszTokens);
    }

    bEOF = true;
    delete poLS;
    return nullptr;
}
Пример #18
0
void ILI1Reader::ReadGeom(char **stgeom, int geomIdx, OGRwkbGeometryType eType, OGRFeature *feature) {
    char **tokens = NULL;
    const char *firsttok = NULL;
    int end = FALSE;
    OGRCompoundCurve *ogrCurve = NULL; //current compound curve
    OGRLineString *ogrLine = NULL; //current line
    OGRCircularString *arc = NULL; //current arc
    OGRCurvePolygon *ogrPoly = NULL; //current polygon
    OGRPoint ogrPoint; //current point
    OGRMultiCurve *ogrMultiLine = NULL; //current multi line

    //CPLDebug( "OGR_ILI", "ILI1Reader::ReadGeom geomIdx: %d OGRGeometryType: %s", geomIdx, OGRGeometryTypeToName(eType));
    if (eType == wkbNone)
    {
      CPLError(CE_Warning, CPLE_AppDefined, "Calling ILI1Reader::ReadGeom with wkbNone" );
    }

    //Initialize geometry

    ogrCurve = new OGRCompoundCurve();

    if (eType == wkbMultiCurve || eType == wkbMultiLineString)
    {
      ogrMultiLine = new OGRMultiCurve();
    }
    else if (eType == wkbPolygon || eType == wkbCurvePolygon)
    {
      ogrPoly = new OGRCurvePolygon();
    }

    //tokens = ["STPT", "1111", "22222"]
    ogrPoint.setX(CPLAtof(stgeom[1])); ogrPoint.setY(CPLAtof(stgeom[2]));
    ogrLine = new OGRLineString();
    ogrLine->addPoint(&ogrPoint);

    //Parse geometry
    while (!end && (tokens = ReadParseLine()))
    {
      firsttok = CSLGetField(tokens, 0);
      if (EQUAL(firsttok, "LIPT"))
      {
        ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2]));
        if (arc) {
          arc->addPoint(&ogrPoint);
          ogrCurve->addCurveDirectly(arc);
          arc = NULL;
        }
        ogrLine->addPoint(&ogrPoint);
      }
      else if (EQUAL(firsttok, "ARCP"))
      {
        //Finish line and start arc
        if (ogrLine->getNumPoints() > 1) {
          ogrCurve->addCurveDirectly(ogrLine);
          ogrLine = new OGRLineString();
        } else {
          ogrLine->empty();
        }
        arc = new OGRCircularString();
        arc->addPoint(&ogrPoint);
        ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2]));
        arc->addPoint(&ogrPoint);
      }
      else if (EQUAL(firsttok, "ELIN"))
      {
        if (!ogrLine->IsEmpty()) {
          ogrCurve->addCurveDirectly(ogrLine);
        }
        if (!ogrCurve->IsEmpty()) {
          if (ogrMultiLine)
          {
            ogrMultiLine->addGeometryDirectly(ogrCurve);
          }
          if (ogrPoly)
          {
            ogrPoly->addRingDirectly(ogrCurve);
          }
        }
        end = TRUE;
      }
      else if (EQUAL(firsttok, "EEDG"))
      {
        end = TRUE;
      }
      else if (EQUAL(firsttok, "LATT"))
      {
        //Line Attributes (ignored)
      }
      else if (EQUAL(firsttok, "EFLA"))
      {
        end = TRUE;
      }
      else if (EQUAL(firsttok, "ETAB"))
      {
        end = TRUE;
      }
      else
      {
        CPLError(CE_Warning, CPLE_AppDefined, "Unexpected token: %s", firsttok );
      }

      CSLDestroy(tokens);
    }

    //Set feature geometry
    if (eType == wkbMultiCurve)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine);
    }
    else if (eType == wkbMultiLineString)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine->getLinearGeometry());
      delete ogrMultiLine;
    }
    else if (eType == wkbCurvePolygon)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrPoly);
    }
    else if (eType == wkbPolygon)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrPoly->getLinearGeometry());
      delete ogrPoly;
    }
    else
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrCurve);
    }
}
Пример #19
0
static OGRCompoundCurve *getPolyline(DOMElement *elem) {
  // elem -> POLYLINE
  OGRCompoundCurve *ogrCurve = new OGRCompoundCurve();
  OGRLineString *ls = new OGRLineString();

  DOMElement *lineElem = (DOMElement *)elem->getFirstChild();
  while (lineElem != NULL) {
    char* pszTagName = XMLString::transcode(lineElem->getTagName());
    if (cmpStr(ILI2_COORD, pszTagName) == 0)
    {
      OGRPoint* poPoint = getPoint(lineElem);
      ls->addPoint(poPoint);
      delete poPoint;
    }
    else if (cmpStr(ILI2_ARC, pszTagName) == 0) {
      //Finish line and start arc
      if (ls->getNumPoints() > 1) {
        ogrCurve->addCurveDirectly(ls);
        ls = new OGRLineString();
      } else {
        ls->empty();
      }
      OGRCircularString *arc = new OGRCircularString();
      // end point
      OGRPoint *ptEnd = new OGRPoint();
      // point on the arc
      OGRPoint *ptOnArc = new OGRPoint();
      // radius
      // double radius = 0;

      DOMElement *arcElem = (DOMElement *)lineElem->getFirstChild();
      while (arcElem != NULL) {
        char* pszTagName2 = XMLString::transcode(arcElem->getTagName());
        char* pszObjValue = getObjValue(arcElem);
        if (cmpStr("C1", pszTagName2) == 0)
          ptEnd->setX(CPLAtof(pszObjValue));
        else if (cmpStr("C2", pszTagName2) == 0)
          ptEnd->setY(CPLAtof(pszObjValue));
        else if (cmpStr("C3", pszTagName2) == 0)
          ptEnd->setZ(CPLAtof(pszObjValue));
        else if (cmpStr("A1", pszTagName2) == 0)
          ptOnArc->setX(CPLAtof(pszObjValue));
        else if (cmpStr("A2", pszTagName2) == 0)
          ptOnArc->setY(CPLAtof(pszObjValue));
        else if (cmpStr("A3", pszTagName2) == 0)
          ptOnArc->setZ(CPLAtof(pszObjValue));
        else if (cmpStr("R", pszTagName2) == 0) {
          // radius = CPLAtof(pszObjValue);
        }
        CPLFree(pszObjValue);
        XMLString::release(&pszTagName2);

        arcElem = (DOMElement *)arcElem->getNextSibling();
      }

      OGRPoint *ptStart = getPoint((DOMElement *)lineElem->getPreviousSibling()); // COORD or ARC
      arc->addPoint(ptStart);
      arc->addPoint(ptOnArc);
      arc->addPoint(ptEnd);
      ogrCurve->addCurveDirectly(arc);

      delete ptStart;
      delete ptEnd;
      delete ptOnArc;
    } /* else { // TODO: StructureValue in Polyline not yet supported
    } */
    XMLString::release(&pszTagName);

    lineElem = (DOMElement *)lineElem->getNextSibling();
  }

  if (ls->getNumPoints() > 1) {
    ogrCurve->addCurveDirectly(ls);
  }
  else {
    delete ls;
  }
  return ogrCurve;
}
Пример #20
0
OGRErr OGRDXFLayer::CollectBoundaryPath( OGRGeometryCollection *poGC )

{
    int  nCode;
    char szLineBuf[257];

/* -------------------------------------------------------------------- */
/*      Read the boundary path type.                                    */
/* -------------------------------------------------------------------- */
#define BPT_DEFAULT    0
#define BPT_EXTERNAL   1
#define BPT_POLYLINE   2
#define BPT_DERIVED    3
#define BPT_TEXTBOX    4
#define BPT_OUTERMOST  5

    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 92 )
        return NULL;

    int  nBoundaryPathType = atoi(szLineBuf);
    
    // for now we don't implement polyline support.
    if( nBoundaryPathType == BPT_POLYLINE )
    {
        CPLDebug( "DXF", "HATCH polyline boundaries not yet supported." );
        return OGRERR_UNSUPPORTED_OPERATION;
    }

/* -------------------------------------------------------------------- */
/*      Read number of edges.                                           */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 93 )
        return OGRERR_FAILURE;

    int nEdgeCount = atoi(szLineBuf);
    
/* -------------------------------------------------------------------- */
/*      Loop reading edges.                                             */
/* -------------------------------------------------------------------- */
    int iEdge;

    for( iEdge = 0; iEdge < nEdgeCount; iEdge++ )
    {
/* -------------------------------------------------------------------- */
/*      Read the edge type.                                             */
/* -------------------------------------------------------------------- */
#define ET_LINE         1
#define ET_CIRCULAR_ARC 2
#define ET_ELLIPTIC_ARC 3
#define ET_SPLINE       4

        nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
        if( nCode != 72 )
            return OGRERR_FAILURE;

        int nEdgeType = atoi(szLineBuf);
        
/* -------------------------------------------------------------------- */
/*      Process a line edge.                                            */
/* -------------------------------------------------------------------- */
        if( nEdgeType == ET_LINE )
        {
            double dfStartX;
            double dfStartY;
            double dfEndX;
            double dfEndY;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 10 )
                dfStartX = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 20 )
                dfStartY = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 11 )
                dfEndX = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 21 )
                dfEndY = atof(szLineBuf);
            else
                break;

            OGRLineString *poLS = new OGRLineString();

            poLS->addPoint( dfStartX, dfStartY );
            poLS->addPoint( dfEndX, dfEndY );

            poGC->addGeometryDirectly( poLS );
        }
/* -------------------------------------------------------------------- */
/*      Process a circular arc.                                         */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_CIRCULAR_ARC )
        {
            double dfCenterX;
            double dfCenterY;
            double dfRadius;
            double dfStartAngle;
            double dfEndAngle;
            int    bCounterClockwise = FALSE;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 10 )
                dfCenterX = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 20 )
                dfCenterY = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 40 )
                dfRadius = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 50 )
                dfStartAngle = -1 * atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 51 )
                dfEndAngle = -1 * atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 73 )
                bCounterClockwise = atoi(szLineBuf);
            else
                poDS->UnreadValue();

            if( bCounterClockwise )
            {
                double dfTemp = dfStartAngle;
                dfStartAngle = dfEndAngle;
                dfEndAngle = dfTemp;
            }

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;

            OGRGeometry *poArc = OGRGeometryFactory::approximateArcAngles( 
                dfCenterX, dfCenterY, 0.0,
                dfRadius, dfRadius, 0.0,
                dfStartAngle, dfEndAngle, 0.0 );

            poArc->flattenTo2D();

            poGC->addGeometryDirectly( poArc );
        }
        else
        {
            CPLDebug( "DXF", "Unsupported HATCH boundary line type:%d",
                      nEdgeType );
            return OGRERR_UNSUPPORTED_OPERATION;
        }
    }

/* -------------------------------------------------------------------- */
/*      Number of source boundary objects.                              */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 97 )
        poDS->UnreadValue();
    else
    {
        if( atoi(szLineBuf) != 0 )
        {
            CPLDebug( "DXF", "got unsupported HATCH boundary object references." );
            return OGRERR_UNSUPPORTED_OPERATION;
        }
    }

    return OGRERR_NONE;
}
Пример #21
0
/*!
  \brief Load geometry (linestring SBP layer)

  \return number of invalid features
*/
int VFKDataBlock::LoadGeometryLineStringSBP()
{
    int      idxId, idxBp_Id, idxPCB;
    GUIntBig id, ipcb;
    int      nInvalid;
    
    VFKDataBlock *poDataBlockPoints;
    VFKFeature   *poFeature, *poPoint, *poLine;
    
    OGRLineString oOGRLine;
    
    nInvalid  = 0;
    poLine    = NULL;
    
    poDataBlockPoints = (VFKDataBlock *) m_poReader->GetDataBlock("SOBR");
    if (NULL == poDataBlockPoints) {
        CPLError(CE_Failure, CPLE_NotSupported, 
                 "Data block %s not found.\n", m_pszName);
        return nInvalid;
    }
    
    poDataBlockPoints->LoadGeometry();
    idxId    = poDataBlockPoints->GetPropertyIndex("ID");
    idxBp_Id = GetPropertyIndex("BP_ID");
    idxPCB   = GetPropertyIndex("PORADOVE_CISLO_BODU");
    if (idxId < 0 || idxBp_Id < 0 || idxPCB < 0) {
        CPLError(CE_Failure, CPLE_NotSupported, 
                 "Corrupted data (%s).\n", m_pszName);
        return nInvalid;
    }
    
    for (int j = 0; j < ((IVFKDataBlock *) this)->GetFeatureCount(); j++) {
        poFeature = (VFKFeature *) GetFeatureByIndex(j);
        poFeature->SetGeometry(NULL);
        id   = strtoul(poFeature->GetProperty(idxBp_Id)->GetValueS(), NULL, 0);
        ipcb = strtoul(poFeature->GetProperty(idxPCB)->GetValueS(), NULL, 0);
        if (ipcb == 1) {
            if (!oOGRLine.IsEmpty()) {
                oOGRLine.setCoordinateDimension(2); /* force 2D */
                if (!poLine->SetGeometry(&oOGRLine))
                    nInvalid++;
                oOGRLine.empty(); /* restore line */
            }
            poLine = poFeature;
        }
        else {
            poFeature->SetGeometryType(wkbUnknown);
        }
        poPoint = poDataBlockPoints->GetFeature(idxId, id);
        if (!poPoint)
            continue;
        OGRPoint *pt = (OGRPoint *) poPoint->GetGeometry();
        oOGRLine.addPoint(pt);
    }
    /* add last line */
    oOGRLine.setCoordinateDimension(2); /* force 2D */
    if (poLine) {
        if (!poLine->SetGeometry(&oOGRLine))
            nInvalid++;
    }
    poDataBlockPoints->ResetReading();

    return nInvalid;
}
Пример #22
0
OGRFeature *OGRCADLayer::GetFeature( GIntBig nFID )
{
    if( poCADLayer.getGeometryCount() <= static_cast<size_t>(nFID)
        || nFID < 0 )
    {
        return nullptr;
    }

    OGRFeature  *poFeature = nullptr;
    CADGeometry *poCADGeometry = poCADLayer.getGeometry( static_cast<size_t>(nFID) );

    if( nullptr == poCADGeometry || GetLastErrorCode() != CADErrorCodes::SUCCESS )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                 "Failed to get geometry with ID = " CPL_FRMT_GIB " from layer \"%s\". Libopencad errorcode: %d",
                 nFID, poCADLayer.getName().c_str(), GetLastErrorCode() );
        return nullptr;
    }

    poFeature = new OGRFeature( poFeatureDefn );
    poFeature->SetFID( nFID );
    poFeature->SetField( FIELD_NAME_THICKNESS, poCADGeometry->getThickness() );

    if( !poCADGeometry->getEED().empty() )
    {
        std::vector<std::string> asGeometryEED = poCADGeometry->getEED();
        std::string sEEDAsOneString = "";
        for ( std::vector<std::string>::const_iterator
              iter = asGeometryEED.cbegin();
              iter != asGeometryEED.cend(); ++iter )
        {
            sEEDAsOneString += *iter;
            sEEDAsOneString += ' ';
        }

        poFeature->SetField( FIELD_NAME_EXT_DATA, sEEDAsOneString.c_str() );
    }

    RGBColor stRGB = poCADGeometry->getColor();
    CPLString sHexColor;
    sHexColor.Printf("#%02X%02X%02X%02X", stRGB.R, stRGB.G, stRGB.B, 255);
    poFeature->SetField( FIELD_NAME_COLOR, sHexColor );

    CPLString sStyle;
    sStyle.Printf("PEN(c:%s,w:5px)", sHexColor.c_str());
    poFeature->SetStyleString( sStyle );

    std::vector< CADAttrib > oBlockAttrs = poCADGeometry->getBlockAttributes();
    for( const CADAttrib& oAttrib : oBlockAttrs )
    {
        CPLString osTag = oAttrib.getTag();
        auto featureAttrIt = asFeaturesAttributes.find( osTag );
        if( featureAttrIt != asFeaturesAttributes.end())
        {
            poFeature->SetField(*featureAttrIt, oAttrib.getTextValue().c_str());
        }
    }

    switch( poCADGeometry->getType() )
    {
        case CADGeometry::POINT:
        {
            CADPoint3D * const poCADPoint = ( CADPoint3D* ) poCADGeometry;
            CADVector stPositionVector = poCADPoint->getPosition();

            poFeature->SetGeometryDirectly( new OGRPoint( stPositionVector.getX(),
                                                          stPositionVector.getY(),
                                                          stPositionVector.getZ() ) );
            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADPoint" );
            break;
        }

        case CADGeometry::LINE:
        {
            CADLine * const poCADLine = ( CADLine* ) poCADGeometry;
            OGRLineString *poLS = new OGRLineString();
            poLS->addPoint( poCADLine->getStart().getPosition().getX(),
                           poCADLine->getStart().getPosition().getY(),
                           poCADLine->getStart().getPosition().getZ() );
            poLS->addPoint( poCADLine->getEnd().getPosition().getX(),
                           poCADLine->getEnd().getPosition().getY(),
                           poCADLine->getEnd().getPosition().getZ() );

            poFeature->SetGeometryDirectly( poLS );
            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADLine" );
            break;
        }

        case CADGeometry::SOLID:
        {
            CADSolid * const poCADSolid = ( CADSolid* ) poCADGeometry;
            OGRPolygon * poPoly = new OGRPolygon();
            OGRLinearRing * poLR = new OGRLinearRing();

            std::vector<CADVector> astSolidCorners = poCADSolid->getCorners();
            for( size_t i = 0; i < astSolidCorners.size(); ++i )
            {
                poLR->addPoint( astSolidCorners[i].getX(),
                                astSolidCorners[i].getY(),
                                astSolidCorners[i].getZ());
            }
            poPoly->addRingDirectly( poLR );
            poPoly->closeRings();
            poFeature->SetGeometryDirectly( poPoly );

            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADSolid" );
            break;
        }

        case CADGeometry::CIRCLE:
        {
            CADCircle * poCADCircle = static_cast<CADCircle*>(poCADGeometry);
            OGRCircularString * poCircle = new OGRCircularString();

            CADVector stCircleCenter = poCADCircle->getPosition();
            OGRPoint  oCirclePoint1;
            oCirclePoint1.setX( stCircleCenter.getX() - poCADCircle->getRadius() );
            oCirclePoint1.setY( stCircleCenter.getY() );
            oCirclePoint1.setZ( stCircleCenter.getZ() );
            poCircle->addPoint( &oCirclePoint1 );

            OGRPoint  oCirclePoint2;
            oCirclePoint2.setX( stCircleCenter.getX() );
            oCirclePoint2.setY( stCircleCenter.getY() + poCADCircle->getRadius() );
            oCirclePoint2.setZ( stCircleCenter.getZ() );
            poCircle->addPoint( &oCirclePoint2 );

            OGRPoint  oCirclePoint3;
            oCirclePoint3.setX( stCircleCenter.getX() + poCADCircle->getRadius() );
            oCirclePoint3.setY( stCircleCenter.getY() );
            oCirclePoint3.setZ( stCircleCenter.getZ() );
            poCircle->addPoint( &oCirclePoint3 );

            OGRPoint  oCirclePoint4;
            oCirclePoint4.setX( stCircleCenter.getX() );
            oCirclePoint4.setY( stCircleCenter.getY() - poCADCircle->getRadius() );
            oCirclePoint4.setZ( stCircleCenter.getZ() );
            poCircle->addPoint( &oCirclePoint4 );

            // Close the circle
            poCircle->addPoint( &oCirclePoint1 );

            /*NOTE: The alternative way:
                    OGRGeometry *poCircle = OGRGeometryFactory::approximateArcAngles(
                    poCADCircle->getPosition().getX(),
                    poCADCircle->getPosition().getY(),
                    poCADCircle->getPosition().getZ(),
                    poCADCircle->getRadius(), poCADCircle->getRadius(), 0.0,
                    0.0, 360.0,
                    0.0 );
            */
            poFeature->SetGeometryDirectly( poCircle );

            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADCircle" );
            break;
        }

        case CADGeometry::ARC:
        {
            CADArc * poCADArc = static_cast<CADArc*>(poCADGeometry);
            OGRCircularString * poCircle = new OGRCircularString();

            // Need at least 3 points in arc
            double dfStartAngle = poCADArc->getStartingAngle() * DEG2RAD;
            double dfEndAngle = poCADArc->getEndingAngle() * DEG2RAD;
            double dfMidAngle = (dfEndAngle + dfStartAngle) / 2;
            CADVector stCircleCenter = poCADArc->getPosition();

            OGRPoint  oCirclePoint;
            oCirclePoint.setX( stCircleCenter.getX() + poCADArc->getRadius() *
                                                            cos( dfStartAngle ) );
            oCirclePoint.setY( stCircleCenter.getY() + poCADArc->getRadius() *
                                                            sin( dfStartAngle ) );
            oCirclePoint.setZ( stCircleCenter.getZ() );
            poCircle->addPoint( &oCirclePoint );

            oCirclePoint.setX( stCircleCenter.getX() + poCADArc->getRadius() *
                                                            cos( dfMidAngle ) );
            oCirclePoint.setY( stCircleCenter.getY() + poCADArc->getRadius() *
                                                            sin( dfMidAngle ) );
            oCirclePoint.setZ( stCircleCenter.getZ() );
            poCircle->addPoint( &oCirclePoint );

            oCirclePoint.setX( stCircleCenter.getX() + poCADArc->getRadius() *
                                                            cos( dfEndAngle ) );
            oCirclePoint.setY( stCircleCenter.getY() + poCADArc->getRadius() *
                                                            sin( dfEndAngle ) );
            oCirclePoint.setZ( stCircleCenter.getZ() );
            poCircle->addPoint( &oCirclePoint );

            /*NOTE: alternative way:
                OGRGeometry * poArc = OGRGeometryFactory::approximateArcAngles(
                poCADArc->getPosition().getX(),
                poCADArc->getPosition().getY(),
                poCADArc->getPosition().getZ(),
                poCADArc->getRadius(), poCADArc->getRadius(), 0.0,
                dfStartAngle,
                dfStartAngle > dfEndAngle ?
                    ( dfEndAngle + 360.0f ) :
                    dfEndAngle,
                0.0 );
            */

            poFeature->SetGeometryDirectly( poCircle );
            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADArc" );

            break;
        }

        case CADGeometry::FACE3D:
        {
            CADFace3D * const poCADFace = ( CADFace3D* ) poCADGeometry;
            OGRPolygon * poPoly = new OGRPolygon();
            OGRLinearRing * poLR = new OGRLinearRing();

            for ( size_t i = 0; i < 3; ++i )
            {
                poLR->addPoint(
                    poCADFace->getCorner( i ).getX(),
                    poCADFace->getCorner( i ).getY(),
                    poCADFace->getCorner( i ).getZ()
                );
            }
            if ( !(poCADFace->getCorner( 2 ) == poCADFace->getCorner( 3 )) )
            {
                poLR->addPoint(
                    poCADFace->getCorner( 3 ).getX(),
                    poCADFace->getCorner( 3 ).getY(),
                    poCADFace->getCorner( 3 ).getZ()
                );
            }
            poPoly->addRingDirectly( poLR );
            poPoly->closeRings();
            poFeature->SetGeometryDirectly( poPoly );

            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADFace3D" );
            break;
        }

        case CADGeometry::LWPOLYLINE:
        {
            CADLWPolyline * const poCADLWPolyline = ( CADLWPolyline* ) poCADGeometry;

            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADLWPolyline" );

            /*
             * Excessive check, like in DXF driver.
             * I tried to make a single-point polyline, but couldn't make it.
             * Probably this check should be removed.
             */
            if( poCADLWPolyline->getVertexCount() == 1 )
            {
                poFeature->SetGeometryDirectly(
                            new OGRPoint( poCADLWPolyline->getVertex(0).getX(),
                                          poCADLWPolyline->getVertex(0).getY(),
                                          poCADLWPolyline->getVertex(0).getZ() )
                );

                break;
            }

            /*
             * If polyline has no arcs, handle it in easy way.
             */
            OGRLineString * poLS = new OGRLineString();

            if( poCADLWPolyline->getBulges().empty() )
            {
                for( size_t i = 0; i < poCADLWPolyline->getVertexCount(); ++i )
                {
                    CADVector stVertex = poCADLWPolyline->getVertex( i );
                    poLS->addPoint( stVertex.getX(),
                                    stVertex.getY(),
                                    stVertex.getZ()
                    );
                }

                poFeature->SetGeometryDirectly( poLS );
                break;
            }

            /*
             * Last case - if polyline has mixed arcs and lines.
             */
            bool   bLineStringStarted = false;
            std::vector< double > adfBulges = poCADLWPolyline->getBulges();
            const size_t nCount = std::min(adfBulges.size(), poCADLWPolyline->getVertexCount());

            for( size_t iCurrentVertex = 0; iCurrentVertex + 1 < nCount; iCurrentVertex++ )
            {
                CADVector stCurrentVertex = poCADLWPolyline->getVertex( iCurrentVertex );
                CADVector stNextVertex = poCADLWPolyline->getVertex( iCurrentVertex + 1 );

                double dfLength = sqrt( pow( stNextVertex.getX() - stCurrentVertex.getX(), 2 )
                                      + pow( stNextVertex.getY() - stCurrentVertex.getY(), 2 ) );

                /*
                 * Handling straight polyline segment.
                 */
                if( ( dfLength == 0 ) || ( adfBulges[iCurrentVertex] == 0 ) )
                {
                    if( !bLineStringStarted )
                    {
                        poLS->addPoint( stCurrentVertex.getX(),
                                        stCurrentVertex.getY(),
                                        stCurrentVertex.getZ()
                        );
                        bLineStringStarted = true;
                    }

                    poLS->addPoint( stNextVertex.getX(),
                                    stNextVertex.getY(),
                                    stNextVertex.getZ()
                    );
                }
                else
                {
                    double dfSegmentBulge = adfBulges[iCurrentVertex];
                    double dfH = ( dfSegmentBulge * dfLength ) / 2;
                    if( dfH == 0.0 )
                        dfH = 1.0; // just to avoid a division by zero
                    double dfRadius = ( dfH / 2 ) + ( dfLength * dfLength / ( 8 * dfH ) );
                    double dfOgrArcRotation = 0, dfOgrArcRadius = fabs( dfRadius );

                    /*
                     * Set arc's direction and keep bulge positive.
                     */
                    bool   bClockwise = ( dfSegmentBulge < 0 );
                    if( bClockwise )
                        dfSegmentBulge *= -1;

                    /*
                     * Get arc's center point.
                     */
                    double dfSaggita = fabs( dfSegmentBulge * ( dfLength / 2.0 ) );
                    double dfApo = bClockwise ? -( dfOgrArcRadius - dfSaggita ) :
                                                -( dfSaggita - dfOgrArcRadius );

                    CADVector stVertex;
                    stVertex.setX( stCurrentVertex.getX() - stNextVertex.getX() );
                    stVertex.setY( stCurrentVertex.getY() - stNextVertex.getY() );
                    stVertex.setZ( stCurrentVertex.getZ() );

                    CADVector stMidPoint;
                    stMidPoint.setX( stNextVertex.getX() + 0.5 * stVertex.getX() );
                    stMidPoint.setY( stNextVertex.getY() + 0.5 * stVertex.getY() );
                    stMidPoint.setZ( stVertex.getZ() );

                    CADVector stPperp;
                    stPperp.setX( stVertex.getY() );
                    stPperp.setY( -stVertex.getX() );
                    double dfStPperpLength = sqrt( stPperp.getX() * stPperp.getX() +
                                                   stPperp.getY() * stPperp.getY() );
                    // TODO: Check that length isnot 0
                    stPperp.setX( stPperp.getX() / dfStPperpLength );
                    stPperp.setY( stPperp.getY() / dfStPperpLength );

                    CADVector stOgrArcCenter;
                    stOgrArcCenter.setX( stMidPoint.getX() + ( stPperp.getX() * dfApo ) );
                    stOgrArcCenter.setY( stMidPoint.getY() + ( stPperp.getY() * dfApo ) );

                    /*
                     * Get the line's general vertical direction ( -1 = down, +1 = up ).
                     */
                    double dfLineDir = stNextVertex.getY() >
                                            stCurrentVertex.getY() ? 1.0f : -1.0f;

                    /*
                     * Get arc's starting angle.
                     */
                    double dfA = atan2( ( stOgrArcCenter.getY() - stCurrentVertex.getY() ),
                                        ( stOgrArcCenter.getX() - stCurrentVertex.getX() ) ) * DEG2RAD;
                    if( bClockwise && ( dfLineDir == 1.0 ) )
                        dfA += ( dfLineDir * 180.0 );

                    double dfOgrArcStartAngle = dfA > 0.0 ? -( dfA - 180.0 ) :
                                                            -( dfA + 180.0 );

                    /*
                     * Get arc's ending angle.
                     */
                    dfA = atan2( ( stOgrArcCenter.getY() - stNextVertex.getY() ),
                                 ( stOgrArcCenter.getX() - stNextVertex.getX() ) ) * DEG2RAD;
                    if( bClockwise && ( dfLineDir == 1.0 ) )
                        dfA += ( dfLineDir * 180.0 );

                    double dfOgrArcEndAngle = dfA > 0.0 ? -( dfA - 180.0 ) :
                                                          -( dfA + 180.0 );

                    if( !bClockwise && ( dfOgrArcStartAngle < dfOgrArcEndAngle) )
                        dfOgrArcEndAngle = -180.0 + ( dfLineDir * dfA );

                    if( bClockwise && ( dfOgrArcStartAngle > dfOgrArcEndAngle ) )
                        dfOgrArcEndAngle += 360.0;

                    /*
                     * Flip arc's rotation if necessary.
                     */
                    if( bClockwise && ( dfLineDir == 1.0 ) )
                        dfOgrArcRotation = dfLineDir * 180.0;

                    /*
                     * Tessellate the arc segment and append to the linestring.
                     */
                    OGRLineString * poArcpoLS =
                        ( OGRLineString * ) OGRGeometryFactory::approximateArcAngles(
                            stOgrArcCenter.getX(), stOgrArcCenter.getY(), stOgrArcCenter.getZ(),
                            dfOgrArcRadius, dfOgrArcRadius, dfOgrArcRotation,
                            dfOgrArcStartAngle,dfOgrArcEndAngle,
                            0.0 );

                    poLS->addSubLineString( poArcpoLS );

                    delete( poArcpoLS );
                }
            }

            if( poCADLWPolyline->isClosed() )
            {
                poLS->addPoint( poCADLWPolyline->getVertex(0).getX(),
                                poCADLWPolyline->getVertex(0).getY(),
                                poCADLWPolyline->getVertex(0).getZ()
                );
            }

            poFeature->SetGeometryDirectly( poLS );
            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADLWPolyline" );
            break;
        }

        // TODO: Unsupported smooth lines
        case CADGeometry::POLYLINE3D:
        {
            CADPolyline3D * const poCADPolyline3D = ( CADPolyline3D* ) poCADGeometry;
            OGRLineString * poLS = new OGRLineString();

            for( size_t i = 0; i < poCADPolyline3D->getVertexCount(); ++i )
            {
                CADVector stVertex = poCADPolyline3D->getVertex( i );

                poLS->addPoint( stVertex.getX(),
                                stVertex.getY(),
                                stVertex.getZ() );
            }

            poFeature->SetGeometryDirectly( poLS );
            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADPolyline3D" );
            break;
        }

        case CADGeometry::TEXT:
        {
            CADText * const poCADText = ( CADText * ) poCADGeometry;
            OGRPoint * poPoint = new OGRPoint( poCADText->getPosition().getX(),
                                               poCADText->getPosition().getY(),
                                               poCADText->getPosition().getZ() );
            CPLString sTextValue = CADRecode( poCADText->getTextValue(), nDWGEncoding );

            poFeature->SetField( FIELD_NAME_TEXT, sTextValue );
            poFeature->SetGeometryDirectly( poPoint );
            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADText" );

            sStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",c:%s)", sTextValue.c_str(),
                                                              sHexColor.c_str());
            poFeature->SetStyleString( sStyle );
            break;
        }

        case CADGeometry::MTEXT:
        {
            CADMText * const poCADMText = ( CADMText * ) poCADGeometry;
            OGRPoint * poPoint = new OGRPoint( poCADMText->getPosition().getX(),
                                               poCADMText->getPosition().getY(),
                                               poCADMText->getPosition().getZ() );
            CPLString sTextValue = CADRecode( poCADMText->getTextValue(), nDWGEncoding );

            poFeature->SetField( FIELD_NAME_TEXT, sTextValue );
            poFeature->SetGeometryDirectly( poPoint );
            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADMText" );

            sStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",c:%s)", sTextValue.c_str(),
                                                              sHexColor.c_str());
            poFeature->SetStyleString( sStyle );
            break;
        }

        case CADGeometry::SPLINE:
        {
            CADSpline * const poCADSpline = ( CADSpline * ) poCADGeometry;
            OGRLineString * poLS = new OGRLineString();

            // TODO: Interpolate spline as points or curves
            for( size_t i = 0; i < poCADSpline->getControlPoints().size(); ++i )
            {
                poLS->addPoint( poCADSpline->getControlPoints()[i].getX(),
                                poCADSpline->getControlPoints()[i].getY(),
                                poCADSpline->getControlPoints()[i].getZ() );
            }

            poFeature->SetGeometryDirectly( poLS );
            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADSpline" );
            break;
        }

        case CADGeometry::ELLIPSE:
        {
            CADEllipse * poCADEllipse = static_cast<CADEllipse*>(poCADGeometry);

            // FIXME: Start/end angles should be swapped to work exactly as DXF driver.
            // is it correct?
            double dfStartAngle = -1 * poCADEllipse->getEndingAngle() * DEG2RAD;
            double dfEndAngle = -1 * poCADEllipse->getStartingAngle() * DEG2RAD;
            double dfAxisRatio = poCADEllipse->getAxisRatio();

            dfStartAngle = fmod(dfStartAngle, 360.0);
            dfEndAngle = fmod(dfEndAngle, 360.0);
            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;

            CADVector vectPosition = poCADEllipse->getPosition();
            CADVector vectSMAxis = poCADEllipse->getSMAxis();
            double dfPrimaryRadius, dfSecondaryRadius;
            double dfRotation;
            dfPrimaryRadius = sqrt( vectSMAxis.getX() * vectSMAxis.getX()
                                    + vectSMAxis.getY() * vectSMAxis.getY()
                                    + vectSMAxis.getZ() * vectSMAxis.getZ() );

            dfSecondaryRadius = dfAxisRatio * dfPrimaryRadius;

            dfRotation = -1 * atan2( vectSMAxis.getY(), vectSMAxis.getX() ) * DEG2RAD;

            OGRGeometry *poEllipse =
                OGRGeometryFactory::approximateArcAngles(
                    vectPosition.getX(), vectPosition.getY(), vectPosition.getZ(),
                    dfPrimaryRadius, dfSecondaryRadius, dfRotation,
                    dfStartAngle, dfEndAngle, 0.0 );

            poFeature->SetGeometryDirectly( poEllipse );
            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADEllipse" );
            break;
        }

        case CADGeometry::ATTDEF:
        {
            CADAttdef * const poCADAttdef = ( CADAttdef* ) poCADGeometry;
            OGRPoint * poPoint = new OGRPoint( poCADAttdef->getPosition().getX(),
                                               poCADAttdef->getPosition().getY(),
                                               poCADAttdef->getPosition().getZ() );
            CPLString sTextValue = CADRecode( poCADAttdef->getTag(), nDWGEncoding );

            poFeature->SetField( FIELD_NAME_TEXT, sTextValue );
            poFeature->SetGeometryDirectly( poPoint );
            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADAttdef" );

            sStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",c:%s)", sTextValue.c_str(),
                                                              sHexColor.c_str());
            poFeature->SetStyleString( sStyle );
            break;
        }

        default:
        {
            CPLError( CE_Warning, CPLE_NotSupported,
                     "Unhandled feature. Skipping it." );

            poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADUnknown" );
            delete poCADGeometry;
            return poFeature;
        }
    }

    delete poCADGeometry;
    poFeature->GetGeometryRef()->assignSpatialReference( poSpatialRef );
    return poFeature;
}
Пример #23
0
void ILI1Reader::ReadGeom(char **stgeom, OGRwkbGeometryType eType, OGRFeature *feature) {

    char **tokens = NULL;
    const char *firsttok = NULL;
    int end = FALSE;
    int isArc = FALSE;
    OGRLineString *ogrLine = NULL; //current line
    OGRLinearRing *ogrRing = NULL; //current ring
    OGRPolygon *ogrPoly = NULL; //current polygon
    OGRPoint ogrPoint, arcPoint, endPoint; //points for arc interpolation
    OGRMultiLineString *ogrMultiLine = NULL; //current multi line

    //tokens = ["STPT", "1111", "22222"]
    ogrPoint.setX(atof(stgeom[1])); ogrPoint.setY(atof(stgeom[2]));
    ogrLine = (eType == wkbPolygon) ? new OGRLinearRing() : new OGRLineString();
    ogrLine->addPoint(&ogrPoint);

    //Set feature geometry
    if (eType == wkbMultiLineString)
    {
      ogrMultiLine = new OGRMultiLineString();
      feature->SetGeometryDirectly(ogrMultiLine);
    }
    else if (eType == wkbGeometryCollection) //AREA
    {
      if (feature->GetGeometryRef())
        ogrMultiLine = (OGRMultiLineString *)feature->GetGeometryRef();
      else
      {
        ogrMultiLine = new OGRMultiLineString();
        feature->SetGeometryDirectly(ogrMultiLine);
      }
    }
    else if (eType == wkbPolygon)
    {
      if (feature->GetGeometryRef())
      {
        ogrPoly = (OGRPolygon *)feature->GetGeometryRef();
        if (ogrPoly->getNumInteriorRings() > 0)
          ogrRing = ogrPoly->getInteriorRing(ogrPoly->getNumInteriorRings()-1);
        else
          ogrRing = ogrPoly->getExteriorRing();
        if (ogrRing && !ogrRing->get_IsClosed()) ogrLine = ogrRing; //SURFACE polygon spread over multiple OBJECTs
      }
      else
      {
        ogrPoly = new OGRPolygon();
        feature->SetGeometryDirectly(ogrPoly);
      }
    }
    else
    {
      feature->SetGeometryDirectly(ogrLine);
    }

    //Parse geometry
    while (!end && (tokens = ReadParseLine()))
    {
      firsttok = CSLGetField(tokens, 0);
      if (EQUAL(firsttok, "LIPT"))
      {
        if (isArc) {
          endPoint.setX(atof(tokens[1])); endPoint.setY(atof(tokens[2]));
          interpolateArc(ogrLine, &ogrPoint, &arcPoint, &endPoint, arcIncr);
        }
        ogrPoint.setX(atof(tokens[1])); ogrPoint.setY(atof(tokens[2])); isArc = FALSE;
        ogrLine->addPoint(&ogrPoint);
      }
      else if (EQUAL(firsttok, "ARCP"))
      {
        isArc = TRUE;
        arcPoint.setX(atof(tokens[1])); arcPoint.setY(atof(tokens[2]));
      }
      else if (EQUAL(firsttok, "ELIN"))
      {
        if (ogrMultiLine)
        {
          ogrMultiLine->addGeometryDirectly(ogrLine);
        }
        if (ogrPoly && ogrLine != ogrRing)
        {
          ogrPoly->addRingDirectly((OGRLinearRing *)ogrLine);
        }
        end = TRUE;
      }
      else if (EQUAL(firsttok, "EEDG"))
      {
        end = TRUE;
      }
      else if (EQUAL(firsttok, "LATT"))
      {
        //Line Attributes (ignored)
      }
      else if (EQUAL(firsttok, "EFLA"))
      {
        end = TRUE;
      }
      else if (EQUAL(firsttok, "ETAB"))
      {
        end = TRUE;
      }
      else
      {
        CPLDebug( "OGR_ILI", "Unexpected token: %s", firsttok );
      }

      CSLDestroy(tokens);
    }
}
Пример #24
0
OGRFeature *OGRARCGENLayer::GetNextRawFeature()
{
    if (bEOF)
        return NULL;

    const char* pszLine;
    OGRwkbGeometryType eType = poFeatureDefn->GetGeomType();

    if (wkbFlatten(eType) == wkbPoint)
    {
        while(TRUE)
        {
            pszLine = CPLReadLine2L(fp,256,NULL);
            if (pszLine == NULL || EQUAL(pszLine, "END"))
            {
                bEOF = TRUE;
                return NULL;
            }
            char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 );
            int nTokens = CSLCount(papszTokens);
            if (nTokens == 3 || nTokens == 4)
            {
                OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
                poFeature->SetFID(nNextFID ++);
                poFeature->SetField(0, papszTokens[0]);
                if (nTokens == 3)
                    poFeature->SetGeometryDirectly(
                        new OGRPoint(CPLAtof(papszTokens[1]),
                                     CPLAtof(papszTokens[2])));
                else
                    poFeature->SetGeometryDirectly(
                        new OGRPoint(CPLAtof(papszTokens[1]),
                                     CPLAtof(papszTokens[2]),
                                     CPLAtof(papszTokens[3])));
                CSLDestroy(papszTokens);
                return poFeature;
            }
            else
                CSLDestroy(papszTokens);
        }
    }

    CPLString osID;
    OGRLinearRing* poLR =
        (wkbFlatten(eType) == wkbPolygon) ? new OGRLinearRing() : NULL;
    OGRLineString* poLS =
        (wkbFlatten(eType) == wkbLineString) ? new OGRLineString() : poLR;
    while(TRUE)
    {
        pszLine = CPLReadLine2L(fp,256,NULL);
        if (pszLine == NULL)
            break;

        if (EQUAL(pszLine, "END"))
        {
            if (osID.size() == 0)
                break;

            OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
            poFeature->SetFID(nNextFID ++);
            poFeature->SetField(0, osID.c_str());
            if (wkbFlatten(eType) == wkbPolygon)
            {
                OGRPolygon* poPoly = new OGRPolygon();
                poPoly->addRingDirectly(poLR);
                poFeature->SetGeometryDirectly(poPoly);
            }
            else
                poFeature->SetGeometryDirectly(poLS);
            return poFeature;
        }

        char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 );
        int nTokens = CSLCount(papszTokens);
        if (osID.size() == 0)
        {
            if (nTokens >= 1)
                osID = papszTokens[0];
            else
            {
                CSLDestroy(papszTokens);
                break;
            }
        }
        else
        {
            if (nTokens == 2)
            {
                poLS->addPoint(CPLAtof(papszTokens[0]),
                               CPLAtof(papszTokens[1]));
            }
            else if (nTokens == 3)
            {
                poLS->addPoint(CPLAtof(papszTokens[0]),
                               CPLAtof(papszTokens[1]),
                               CPLAtof(papszTokens[2]));
            }
            else
            {
                CSLDestroy(papszTokens);
                break;
            }
        }
        CSLDestroy(papszTokens);
    }

    bEOF = TRUE;
    delete poLS;
    return NULL;
}
Пример #25
0
OGRFeature *TigerCompleteChain::GetFeature( int nRecordId )

{
    char        achRecord[OGR_TIGER_RECBUF_LEN];

    if( nRecordId < 0 || nRecordId >= nFeatures )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Request for out-of-range feature %d of %s1",
                  nRecordId, pszModule );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Read the raw record data from the file.                         */
/* -------------------------------------------------------------------- */
    if( fpPrimary == NULL )
        return NULL;

    if( VSIFSeekL( fpPrimary, (nRecordId+nRT1RecOffset) * nRecordLength, 
                  SEEK_SET ) != 0 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Failed to seek to %d of %s1",
                  nRecordId * nRecordLength, pszModule );
        return NULL;
    }

    if( VSIFReadL( achRecord, psRT1Info->nRecordLength, 1, fpPrimary ) != 1 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Failed to read %d bytes of record %d of %s1 at offset %d",
                  psRT1Info->nRecordLength, nRecordId, pszModule,
                  (nRecordId+nRT1RecOffset) * nRecordLength );
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Set fields.                                                     */
    /* -------------------------------------------------------------------- */

    OGRFeature  *poFeature = new OGRFeature( poFeatureDefn );

    SetFields( psRT1Info, poFeature, achRecord );

    /* -------------------------------------------------------------------- */
    /*      Read RT3 record, and apply fields.                              */
    /* -------------------------------------------------------------------- */

    if( fpRT3 != NULL )
    {
        char    achRT3Rec[OGR_TIGER_RECBUF_LEN];
        int     nRT3RecLen = psRT3Info->nRecordLength + nRecordLength - psRT1Info->nRecordLength;

        if( VSIFSeekL( fpRT3, nRecordId * nRT3RecLen, SEEK_SET ) != 0 )
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Failed to seek to %d of %s3",
                      nRecordId * nRT3RecLen, pszModule );
            return NULL;
        }

        if( VSIFReadL( achRT3Rec, psRT3Info->nRecordLength, 1, fpRT3 ) != 1 )
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Failed to read record %d of %s3",
                      nRecordId, pszModule );
            return NULL;
        }

        SetFields( psRT3Info, poFeature, achRT3Rec );

    }

/* -------------------------------------------------------------------- */
/*      Set geometry                                                    */
/* -------------------------------------------------------------------- */
    OGRLineString       *poLine = new OGRLineString();

    poLine->setPoint(0,
                     atoi(GetField(achRecord, 191, 200)) / 1000000.0,
                     atoi(GetField(achRecord, 201, 209)) / 1000000.0 );

    if( !AddShapePoints( poFeature->GetFieldAsInteger("TLID"), nRecordId,
                         poLine, 0 ) )
    {
        delete poFeature;
        return NULL;
    }
    
    poLine->addPoint(atoi(GetField(achRecord, 210, 219)) / 1000000.0,
                     atoi(GetField(achRecord, 220, 228)) / 1000000.0 );

    poFeature->SetGeometryDirectly( poLine );

    return poFeature;
}
Пример #26
0
OGRFeature *OGRAeronavFAARouteLayer::GetNextRawFeature()
{
    OGRFeature* poFeature = nullptr;
    OGRLineString* poLS = nullptr;

    while( true )
    {
        const char* pszLine = nullptr;
        if (!osLastReadLine.empty())
            pszLine = osLastReadLine.c_str();
        else
            pszLine = CPLReadLine2L(fpAeronavFAA, 87, nullptr);
        osLastReadLine = "";

        if (pszLine == nullptr)
        {
            bEOF = true;
            break;
        }
        if (strlen(pszLine) != 85)
            continue;

        if (bIsDPOrSTARS && STARTS_WITH(pszLine, "===") && pszLine[3] != '=')
        {
            osAPTName = pszLine + 3;
            const char* pszComma = strchr(pszLine + 3, ',');
            if (pszComma)
            {
                osAPTName.resize(pszComma - (pszLine + 3));
                osStateName = pszComma + 2;
                const char* pszEqual = strchr(pszComma + 2, '=');
                if (pszEqual)
                    osStateName.resize(pszEqual - (pszComma + 2));
            }
            else
            {
                const char* pszEqual = strchr(pszLine + 3, '=');
                if (pszEqual)
                    osAPTName.resize(pszEqual - (pszLine + 3));
                osStateName = "";
            }
        }

        if (STARTS_WITH(pszLine + 2, "FACILITY OR"))
            continue;
        if (STARTS_WITH(pszLine + 2, "INTERSECTION"))
            continue;

        if (strcmp(pszLine, "================================DELETIONS LIST=================================198326") == 0)
        {
            bEOF = true;
            break;
        }

        if (poFeature == nullptr)
        {
            if (pszLine[2] == ' ' || pszLine[2] == '-' )
            {
                continue;
            }

            if (STARTS_WITH(pszLine + 29, "                    ") ||
                strchr(pszLine, '(') != nullptr)
            {
                CPLString osName = pszLine + 2;
                osName.resize(60);
                while(!osName.empty() && osName.back() == ' ')
                {
                    osName.resize(osName.size()-1);
                }

                if (strcmp(osName.c_str(), "(DELETIONS LIST)") == 0)
                {
                    bEOF = true;
                    return nullptr;
                }

                poFeature = new OGRFeature(poFeatureDefn);
                poFeature->SetFID(nNextFID ++);
                if (bIsDPOrSTARS)
                {
                    poFeature->SetField(0, osAPTName);
                    poFeature->SetField(1, osStateName);
                    poFeature->SetField(2, osName);
                }
                else
                    poFeature->SetField(0, osName);
                poLS = new OGRLineString();
            }
            continue;
        }

        if (STARTS_WITH(pszLine, "                                                                                    0"))
        {
            if (poLS->getNumPoints() == 0)
                continue;
            else
                break;
        }

        if (pszLine[29 - 1] == ' ' && pszLine[42 - 1] == ' ')
            continue;
        if (strstr(pszLine, "RWY") || strchr(pszLine, '('))
        {
            osLastReadLine = pszLine;
            break;
        }

        double dfLat = 0.0;
        double dfLon = 0.0;
        GetLatLon(pszLine + 29 - 1,
                  pszLine + 42 - 1,
                  dfLat,
                  dfLon);
        poLS->addPoint(dfLon, dfLat);
    }

    if( poFeature != nullptr )
        poFeature->SetGeometryDirectly(poLS);
    return poFeature;
}
Пример #27
0
static int OGR2GML3GeometryAppend( const OGRGeometry *poGeometry,
                                   const OGRSpatialReference* poParentSRS,
                                   char **ppszText, int *pnLength,
                                   int *pnMaxLength,
                                   int bIsSubGeometry,
                                   int bLongSRS,
                                   int bLineStringAsCurve,
                                   const char* pszGMLId,
                                   int nSRSDimensionLocFlags,
                                   int bForceLineStringAsLinearRing )

{

/* -------------------------------------------------------------------- */
/*      Check for Spatial Reference System attached to given geometry   */
/* -------------------------------------------------------------------- */

    // Buffer for srsName, srsDimension and gml:id attributes (srsName="..." gml:id="...")
    char szAttributes[256];
    int nAttrsLength = 0;

    szAttributes[0] = 0;

    const OGRSpatialReference* poSRS = NULL;
    if (poParentSRS)
        poSRS = poParentSRS;
    else
        poParentSRS = poSRS = poGeometry->getSpatialReference();

    int bCoordSwap = FALSE;

    if( NULL != poSRS )
    {
        const char* pszAuthName = NULL;
        const char* pszAuthCode = NULL;
        const char* pszTarget = NULL;

        if (poSRS->IsProjected())
            pszTarget = "PROJCS";
        else
            pszTarget = "GEOGCS";

        pszAuthName = poSRS->GetAuthorityName( pszTarget );
        if( NULL != pszAuthName )
        {
            if( EQUAL( pszAuthName, "EPSG" ) )
            {
                pszAuthCode = poSRS->GetAuthorityCode( pszTarget );
                if( NULL != pszAuthCode && strlen(pszAuthCode) < 10 )
                {
                    if (bLongSRS && !(((OGRSpatialReference*)poSRS)->EPSGTreatsAsLatLong() ||
                                      ((OGRSpatialReference*)poSRS)->EPSGTreatsAsNorthingEasting()))
                    {
                        OGRSpatialReference oSRS;
                        if (oSRS.importFromEPSGA(atoi(pszAuthCode)) == OGRERR_NONE)
                        {
                            if (oSRS.EPSGTreatsAsLatLong() || oSRS.EPSGTreatsAsNorthingEasting())
                                bCoordSwap = TRUE;
                        }
                    }

                    if (!bIsSubGeometry)
                    {
                        if (bLongSRS)
                        {
                            snprintf( szAttributes, sizeof(szAttributes),
                                      " srsName=\"urn:ogc:def:crs:%s::%s\"",
                                      pszAuthName, pszAuthCode );
                        }
                        else
                        {
                            snprintf( szAttributes, sizeof(szAttributes),
                                      " srsName=\"%s:%s\"",
                                      pszAuthName, pszAuthCode );
                        }

                        nAttrsLength = strlen(szAttributes);
                    }
                }
            }
        }
    }

    if( (nSRSDimensionLocFlags & SRSDIM_LOC_GEOMETRY) != 0 &&
        wkbHasZ(poGeometry->getGeometryType()) )
    {
        strcat(szAttributes, " srsDimension=\"3\"");
        nAttrsLength = strlen(szAttributes);

        nSRSDimensionLocFlags &= ~SRSDIM_LOC_GEOMETRY;
    }

    if (pszGMLId != NULL && nAttrsLength + 9 + strlen(pszGMLId) + 1 < sizeof(szAttributes))
    {
        strcat(szAttributes, " gml:id=\"");
        strcat(szAttributes, pszGMLId);
        strcat(szAttributes, "\"");
        nAttrsLength = strlen(szAttributes);
    }

    OGRwkbGeometryType eType = poGeometry->getGeometryType();
    OGRwkbGeometryType eFType = wkbFlatten(eType);

/* -------------------------------------------------------------------- */
/*      2D Point                                                        */
/* -------------------------------------------------------------------- */
    if( eType == wkbPoint )
    {
        char    szCoordinate[256];
        OGRPoint *poPoint = (OGRPoint *) poGeometry;

        if (bCoordSwap)
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getY(), poPoint->getX(), 0.0, 2 );
        else
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getX(), poPoint->getY(), 0.0, 2 );

        _GrowBuffer( *pnLength + strlen(szCoordinate) + 60 + nAttrsLength,
                     ppszText, pnMaxLength );

        sprintf( *ppszText + *pnLength,
                "<gml:Point%s><gml:pos>%s</gml:pos></gml:Point>",
                 szAttributes, szCoordinate );

        *pnLength += strlen( *ppszText + *pnLength );
    }
/* -------------------------------------------------------------------- */
/*      3D Point                                                        */
/* -------------------------------------------------------------------- */
    else if( eType == wkbPoint25D )
    {
        char    szCoordinate[256];
        OGRPoint *poPoint = (OGRPoint *) poGeometry;

        if (bCoordSwap)
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getY(), poPoint->getX(), poPoint->getZ(), 3 );
        else
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getX(), poPoint->getY(), poPoint->getZ(), 3 );

        _GrowBuffer( *pnLength + strlen(szCoordinate) + 70 + nAttrsLength,
                     ppszText, pnMaxLength );

        sprintf( *ppszText + *pnLength,
                "<gml:Point%s><gml:pos>%s</gml:pos></gml:Point>",
                 szAttributes, szCoordinate );

        *pnLength += strlen( *ppszText + *pnLength );
    }

/* -------------------------------------------------------------------- */
/*      LineString and LinearRing                                       */
/* -------------------------------------------------------------------- */
    else if( eFType == wkbLineString )
    {
        int bRing = EQUAL(poGeometry->getGeometryName(),"LINEARRING") ||
                    bForceLineStringAsLinearRing;
        if (!bRing && bLineStringAsCurve)
        {
            AppendString( ppszText, pnLength, pnMaxLength,
                            "<gml:Curve" );
            AppendString( ppszText, pnLength, pnMaxLength,
                            szAttributes );
            AppendString( ppszText, pnLength, pnMaxLength,
                            "><gml:segments><gml:LineStringSegment>" );
            AppendGML3CoordinateList( (OGRLineString *) poGeometry, bCoordSwap,
                                ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags );
            AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:LineStringSegment></gml:segments></gml:Curve>" );
        }
        else
        {
            // Buffer for tag name + srsName attribute if set
            const size_t nLineTagLength = 16;
            char* pszLineTagName = NULL;
            pszLineTagName = (char *) CPLMalloc( nLineTagLength + nAttrsLength + 1 );

            if( bRing )
            {
                /* LinearRing isn't supposed to have srsName attribute according to GML3 SF-0 */
                AppendString( ppszText, pnLength, pnMaxLength,
                            "<gml:LinearRing>" );
            }
            else
            {
                sprintf( pszLineTagName, "<gml:LineString%s>", szAttributes );

                AppendString( ppszText, pnLength, pnMaxLength,
                            pszLineTagName );
            }

            // FREE TAG BUFFER
            CPLFree( pszLineTagName );

            AppendGML3CoordinateList( (OGRLineString *) poGeometry, bCoordSwap,
                                ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags );

            if( bRing )
                AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:LinearRing>" );
            else
                AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:LineString>" );
        }
    }

/* -------------------------------------------------------------------- */
/*      ArcString or Circle                                             */
/* -------------------------------------------------------------------- */
    else if( eFType == wkbCircularString )
    {
        AppendString( ppszText, pnLength, pnMaxLength,
                        "<gml:Curve" );
        AppendString( ppszText, pnLength, pnMaxLength,
                        szAttributes );
        OGRSimpleCurve* poSC = (OGRSimpleCurve *) poGeometry;
        /* SQL MM has a unique type for arc and circle, GML not */
        if( poSC->getNumPoints() == 3 &&
            poSC->getX(0) == poSC->getX(2) &&
            poSC->getY(0) == poSC->getY(2) )
        {
            double dfMidX = (poSC->getX(0) + poSC->getX(1)) / 2;
            double dfMidY = (poSC->getY(0) + poSC->getY(1)) / 2;
            double dfDirX = (poSC->getX(1) - poSC->getX(0)) / 2;
            double dfDirY = (poSC->getY(1) - poSC->getY(0)) / 2;
            double dfNormX = -dfDirY;
            double dfNormY = dfDirX;
            double dfNewX = dfMidX + dfNormX;
            double dfNewY = dfMidY + dfNormY;
            OGRLineString* poLS = new OGRLineString();
            OGRPoint p;
            poSC->getPoint(0, &p);
            poLS->addPoint(&p);
            poSC->getPoint(1, &p);
            if( poSC->getCoordinateDimension() == 3 )
                poLS->addPoint(dfNewX, dfNewY, p.getZ());
            else
                poLS->addPoint(dfNewX, dfNewY);
            poLS->addPoint(&p);
            AppendString( ppszText, pnLength, pnMaxLength,
                            "><gml:segments><gml:Circle>" );
            AppendGML3CoordinateList( poLS, bCoordSwap,
                                ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags );
            AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:Circle></gml:segments></gml:Curve>" );
            delete poLS;
        }
        else
        {
            AppendString( ppszText, pnLength, pnMaxLength,
                            "><gml:segments><gml:ArcString>" );
            AppendGML3CoordinateList( poSC, bCoordSwap,
                                ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags );
            AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:ArcString></gml:segments></gml:Curve>" );
        }
    }

/* -------------------------------------------------------------------- */
/*      CompositeCurve                                                  */
/* -------------------------------------------------------------------- */
    else if( eFType == wkbCompoundCurve )
    {
        AppendString( ppszText, pnLength, pnMaxLength,
                        "<gml:CompositeCurve" );
        AppendString( ppszText, pnLength, pnMaxLength,
                        szAttributes );
        AppendString( ppszText, pnLength, pnMaxLength,">");

        OGRCompoundCurve* poCC = (OGRCompoundCurve*)poGeometry;
        for(int i=0;i<poCC->getNumCurves();i++)
        {
            AppendString( ppszText, pnLength, pnMaxLength,
                          "<gml:curveMember>" );
            if( !OGR2GML3GeometryAppend( poCC->getCurve(i), poSRS, ppszText, pnLength,
                                         pnMaxLength, TRUE, bLongSRS,
                                         bLineStringAsCurve,
                                         NULL, nSRSDimensionLocFlags, FALSE) )
                return FALSE;
            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:curveMember>" );
        }
        AppendString( ppszText, pnLength, pnMaxLength,
                      "</gml:CompositeCurve>" );
    }

/* -------------------------------------------------------------------- */
/*      Polygon                                                         */
/* -------------------------------------------------------------------- */
    else if( eFType == wkbPolygon || eFType == wkbCurvePolygon )
    {
        OGRCurvePolygon      *poCP = (OGRCurvePolygon *) poGeometry;

        // Buffer for polygon tag name + srsName attribute if set
        const size_t nPolyTagLength = 13;
        char* pszPolyTagName = NULL;
        pszPolyTagName = (char *) CPLMalloc( nPolyTagLength + nAttrsLength + 1 );

        // Compose Polygon tag with or without srsName attribute
        sprintf( pszPolyTagName, "<gml:Polygon%s>", szAttributes );

        AppendString( ppszText, pnLength, pnMaxLength,
                      pszPolyTagName );

        // FREE TAG BUFFER
        CPLFree( pszPolyTagName );

        // Don't add srsName to polygon rings

        if( poCP->getExteriorRingCurve() != NULL )
        {
            AppendString( ppszText, pnLength, pnMaxLength,
                          "<gml:exterior>" );

            if( !OGR2GML3GeometryAppend( poCP->getExteriorRingCurve(), poSRS,
                                         ppszText, pnLength, pnMaxLength,
                                         TRUE, bLongSRS, bLineStringAsCurve,
                                         NULL, nSRSDimensionLocFlags, TRUE) )
            {
                return FALSE;
            }

            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:exterior>" );
        }

        for( int iRing = 0; iRing < poCP->getNumInteriorRings(); iRing++ )
        {
            OGRCurve *poRing = poCP->getInteriorRingCurve(iRing);

            AppendString( ppszText, pnLength, pnMaxLength,
                          "<gml:interior>" );

            if( !OGR2GML3GeometryAppend( poRing, poSRS, ppszText, pnLength,
                                         pnMaxLength, TRUE, bLongSRS,
                                         bLineStringAsCurve,
                                         NULL, nSRSDimensionLocFlags, TRUE) )
                return FALSE;

            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:interior>" );
        }

        AppendString( ppszText, pnLength, pnMaxLength,
                      "</gml:Polygon>" );
    }

/* -------------------------------------------------------------------- */
/*      MultiSurface, MultiCurve, MultiPoint, MultiGeometry             */
/* -------------------------------------------------------------------- */
    else if( eFType == wkbMultiPolygon
             || eFType == wkbMultiSurface
             || eFType == wkbMultiLineString
             || eFType == wkbMultiCurve
             || eFType == wkbMultiPoint
             || eFType == wkbGeometryCollection )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry;
        int             iMember;
        const char *pszElemClose = NULL;
        const char *pszMemberElem = NULL;

        // Buffer for opening tag + srsName attribute
        char* pszElemOpen = NULL;

        if( eFType == wkbMultiPolygon || eFType == wkbMultiSurface )
        {
            pszElemOpen = (char *) CPLMalloc( 13 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiSurface%s>", szAttributes );

            pszElemClose = "MultiSurface>";
            pszMemberElem = "surfaceMember>";
        }
        else if( eFType == wkbMultiLineString || eFType == wkbMultiCurve )
        {
            pszElemOpen = (char *) CPLMalloc( 16 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiCurve%s>", szAttributes );

            pszElemClose = "MultiCurve>";
            pszMemberElem = "curveMember>";
        }
        else if( eFType == wkbMultiPoint )
        {
            pszElemOpen = (char *) CPLMalloc( 11 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiPoint%s>", szAttributes );

            pszElemClose = "MultiPoint>";
            pszMemberElem = "pointMember>";
        }
        else
        {
            pszElemOpen = (char *) CPLMalloc( 19 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiGeometry%s>", szAttributes );

            pszElemClose = "MultiGeometry>";
            pszMemberElem = "geometryMember>";
        }

        AppendString( ppszText, pnLength, pnMaxLength, "<gml:" );
        AppendString( ppszText, pnLength, pnMaxLength, pszElemOpen );

        for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
        {
            OGRGeometry *poMember = poGC->getGeometryRef( iMember );

            AppendString( ppszText, pnLength, pnMaxLength, "<gml:" );
            AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );

            char* pszGMLIdSub = NULL;
            if (pszGMLId != NULL)
                pszGMLIdSub = CPLStrdup(CPLSPrintf("%s.%d", pszGMLId, iMember));

            if( !OGR2GML3GeometryAppend( poMember, poSRS,
                                         ppszText, pnLength, pnMaxLength,
                                         TRUE, bLongSRS, bLineStringAsCurve,
                                         pszGMLIdSub, nSRSDimensionLocFlags, FALSE ) )
            {
                CPLFree(pszGMLIdSub);
                return FALSE;
            }

            CPLFree(pszGMLIdSub);

            AppendString( ppszText, pnLength, pnMaxLength, "</gml:" );
            AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );
        }

        AppendString( ppszText, pnLength, pnMaxLength, "</gml:" );
        AppendString( ppszText, pnLength, pnMaxLength, pszElemClose );

        // FREE TAG BUFFER
        CPLFree( pszElemOpen );
    }
    else
    {
        CPLError(CE_Failure, CPLE_NotSupported, "Unsupported geometry type %s",
                 OGRGeometryTypeToName(eType));
        return FALSE;
    }

    return TRUE;
}
Пример #28
0
void CDlg_GISDataExchange::ExportToGISFile(LPCTSTR lpszCSVFileName,LPCTSTR lpszShapeFileName, CString GISTypeString )
{

#ifndef _WIN64

	m_MessageList.ResetContent ();

	CWaitCursor wait;
	CCSVParser parser;
	int i= 0;


	// open csv file
	if (parser.OpenCSVFile(lpszCSVFileName))
	{

		CString message_str;

		OGRSFDriver *poDriver;

		OGRRegisterAll();

		poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(GISTypeString );
		if( poDriver == NULL )
		{
			message_str.Format ( "%s driver not available.", GISTypeString );
			m_MessageList.AddString (message_str);
			return;
		}

		OGRDataSource *poDS;

		poDS = poDriver->CreateDataSource(lpszShapeFileName, NULL );
		if( poDS == NULL )
		{
			message_str.Format ( "Creation of GIS output file %s failed.\nPlease do not overwrite the exiting file and please select a new file name.", 
				lpszShapeFileName );
			m_MessageList.AddString (message_str);
			return;
		}

		///// export to link layer

		// link layer 

		OGRLayer *poLayer;
		poLayer = poDS->CreateLayer( "link", NULL, wkbLineString, NULL );
		if( poLayer == NULL )
		{
			m_MessageList.AddString ("link Layer creation failed");
			return;
		}



		vector<string> HeaderVector = parser.GetHeaderVector();

		std::vector <CString> LongFieldVector;
		for(unsigned int i = 0; i < HeaderVector.size(); i++)
		{
			if(HeaderVector[i].find ("geometry") !=  string::npos||  HeaderVector[i].find ("name") !=  string::npos || HeaderVector[i].find ("code") !=  string::npos)
			{
				OGRFieldDefn oField (HeaderVector[i].c_str (), OFTString);

				CString str;  
				if( poLayer->CreateField( &oField ) != OGRERR_NONE ) 
				{ 
					str.Format("Creating field %s failed", oField.GetNameRef()); 

					m_MessageList.AddString (str);
					return; 

				}
			}else
			{
				CString field_string  = HeaderVector[i].c_str ();

				OGRFieldDefn oField (field_string, OFTReal);

				CString str;  
				if( poLayer->CreateField( &oField ) != OGRERR_NONE ) 
				{ 
					str.Format("Creating field %s failed", oField.GetNameRef()); 

					m_MessageList.AddString (str);
					return; 
				}

			}

			if(HeaderVector[i].size()>=11)
			{
				LongFieldVector.push_back (HeaderVector[i].c_str ());
			}

		}

		message_str.Format ("%d fields have been created.",HeaderVector.size());
		m_MessageList.AddString (message_str);

		if(LongFieldVector.size() >=1)
		{
			message_str.Format("Warning: Arc GIS file only supports field names with not more than 10 characters.\nThe following fields have long field names. "); 
			m_MessageList.AddString (message_str);
			for(unsigned l = 0; l< LongFieldVector.size(); l++)
			{
				message_str.Format ("%s",LongFieldVector[l]);
				m_MessageList.AddString (message_str);


			}
		}

		int count = 0 ;
		while(parser.ReadRecord())
		{
			//create feature
			OGRFeature *poFeature;
			poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );

			//step 1: write all fields except geometry
			for(unsigned int i = 0; i < HeaderVector.size(); i++)
			{
				if(HeaderVector[i]!="geometry")
				{
					if(HeaderVector[i].find ("name") !=  string::npos || HeaderVector[i].find ("code") !=  string::npos)
					{

						std::string str_value;

						parser.GetValueByFieldName(HeaderVector[i],str_value);

						//							TRACE("field: %s, value = %s\n",HeaderVector[i].c_str (),str_value.c_str ());
						poFeature->SetField(i,str_value.c_str ());
					}else
					{
						double value = 0;

						parser.GetValueByFieldName(HeaderVector[i],value);

						//							TRACE("field: %s, value = %f\n",HeaderVector[i].c_str (),value);

						CString field_name = HeaderVector[i].c_str ();
						poFeature->SetField(i,value);



					}

				}
			}

			string geo_string;
			std::vector<CCoordinate> CoordinateVector;
			if(parser.GetValueByFieldName("geometry",geo_string))
			{
				// overwrite when the field "geometry" exists
				CGeometry geometry(geo_string);
				CoordinateVector = geometry.GetCoordinateList();

				if( m_GIS_data_type == GIS_Point_Type && CoordinateVector.size ()==1)
				{
					OGRPoint pt;
					pt.setX( CoordinateVector[0].X );
					pt.setY( CoordinateVector[0].Y);
					poFeature->SetGeometry( &pt ); 

				}



				if( m_GIS_data_type == GIS_Line_Type)
				{


					OGRLineString line;
					for(unsigned int si = 0; si< CoordinateVector.size(); si++)
					{
						line.addPoint (CoordinateVector[si].X , CoordinateVector[si].Y);
					}

					poFeature->SetGeometry( &line ); 
				}


				if( m_GIS_data_type == GIS_Polygon_Type)
				{

					OGRPolygon polygon;
					OGRLinearRing  ring;

					for(unsigned int si = 0; si<  CoordinateVector.size(); si++)
					{
						ring.addPoint (CoordinateVector[si].X , CoordinateVector[si].Y,1);
					}

					polygon.addRing(&ring);

					poFeature->SetGeometry( &polygon ); 

				}


			} else
			{ // no geometry field


				/// create geometry data from m_GIS_data_type == GIS_Point_Type

				if( m_GIS_data_type == GIS_Point_Type )
				{

					double x, y;
					if(parser.GetValueByFieldName("x",x) && parser.GetValueByFieldName("y",y) )
					{
						OGRPoint pt;
						pt.setX( CoordinateVector[0].X );
						pt.setY( CoordinateVector[0].Y);
						poFeature->SetGeometry( &pt ); 

					}else
					{
						AfxMessageBox("Pleaes prepare fields x and y in the csv file in order to create a node GIS layer.", MB_ICONINFORMATION);
						return;

					}

				}

				///create geometry

				if( m_GIS_data_type == GIS_Line_Type)
				{

					int number_of_shape_points = 0;
					if(parser.GetValueByFieldName("number_of_shape_points", number_of_shape_points))
					{

						if(number_of_shape_points>=2)
						{

							OGRLineString line;

							for(int s= 1; s<= number_of_shape_points; s++)
							{
								CString str_x, str_y;
								str_x.Format ("x%d",s);
								str_y.Format ("y%d",s);
								double x = 0;
								double y = 0;

								string string_x, string_y;
								string_x  = m_pDoc->CString2StdString (str_x);
								string_y  = m_pDoc->CString2StdString (str_y);

								if(parser.GetValueByFieldName(string_x, x) && parser.GetValueByFieldName(string_y, y))
								{
									line.addPoint(x,y);
								}else
								{
									AfxMessageBox("Pleaes prepare fields x1,y1,x2,y2,...,xn,yn in the csv file in order to create a link GIS layer.", MB_ICONINFORMATION);

									return; 
								}


							}
							poFeature->SetGeometry( &line ); 

						}

					}else
					{ 
						AfxMessageBox("Pleaes prepare fields number_of_shape_points, x1,y1,x2,y2,...,xn,yn in the csv file in order to create a link GIS layer.", MB_ICONINFORMATION);
						return;
					}


				}

				// 


				if( m_GIS_data_type == GIS_Polygon_Type)
				{

					OGRPolygon polygon;
					OGRLinearRing  ring;

					int number_of_shape_points = 0;
					if(parser.GetValueByFieldName("number_of_shape_points", number_of_shape_points))
					{

						if(number_of_shape_points>=2)
						{

							OGRLineString line;

							for(int s= 0; s< number_of_shape_points; s++)
							{
								CString str_x, str_y;
								str_x.Format ("x%d",str_x);
								str_y.Format ("y%d",str_y);
								double x = 0;
								double y = 0;

								string string_x, string_y;
								string_x  = m_pDoc->CString2StdString (str_x);
								string_y  = m_pDoc->CString2StdString (str_y);

								if(parser.GetValueByFieldName(string_x, x) && parser.GetValueByFieldName(string_y, y))
								{
									ring.addPoint (x,y,1);
								}else
								{
									AfxMessageBox("Pleaes prepare fields x1,y1,x2,y2,...,xn,yn in the csv file in order to create a zone GIS layer.", MB_ICONINFORMATION);

									return; 
								}

							}
							polygon.addRing(&ring);

							poFeature->SetGeometry( &polygon ); 

						}


					}


				}

			}


			if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
			{
				AfxMessageBox("Failed to create line feature in shapefile.\n");
				return;

			}  

			OGRFeature::DestroyFeature( poFeature );

			count++;
		}

		message_str.Format ("%d records have been created.",count);
		m_MessageList.AddString (message_str);


		OGRDataSource::DestroyDataSource( poDS );

		CString ShapeFile = lpszShapeFileName;
		CString ShapeFileFolder = ShapeFile.Left(ShapeFile.ReverseFind('\\') + 1);

		ShellExecute( NULL,  "explore", ShapeFileFolder, NULL,  NULL, SW_SHOWNORMAL );

	}
#endif

}
OGRErr OGRDXFLayer::CollectBoundaryPath( OGRGeometryCollection *poGC )

{
    int  nCode;
    char szLineBuf[257];

/* -------------------------------------------------------------------- */
/*      Read the boundary path type.                                    */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 92 )
        return OGRERR_FAILURE;

    int  nBoundaryPathType = atoi(szLineBuf);

/* ==================================================================== */
/*      Handle polyline loops.                                          */
/* ==================================================================== */
    if( nBoundaryPathType & 0x02 )
        return CollectPolylinePath( poGC );

/* ==================================================================== */
/*      Handle non-polyline loops.                                      */
/* ==================================================================== */

/* -------------------------------------------------------------------- */
/*      Read number of edges.                                           */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 93 )
        return OGRERR_FAILURE;

    int nEdgeCount = atoi(szLineBuf);
    
/* -------------------------------------------------------------------- */
/*      Loop reading edges.                                             */
/* -------------------------------------------------------------------- */
    int iEdge;

    for( iEdge = 0; iEdge < nEdgeCount; iEdge++ )
    {
/* -------------------------------------------------------------------- */
/*      Read the edge type.                                             */
/* -------------------------------------------------------------------- */
#define ET_LINE         1
#define ET_CIRCULAR_ARC 2
#define ET_ELLIPTIC_ARC 3
#define ET_SPLINE       4

        nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
        if( nCode != 72 )
            return OGRERR_FAILURE;

        int nEdgeType = atoi(szLineBuf);
        
/* -------------------------------------------------------------------- */
/*      Process a line edge.                                            */
/* -------------------------------------------------------------------- */
        if( nEdgeType == ET_LINE )
        {
            double dfStartX;
            double dfStartY;
            double dfEndX;
            double dfEndY;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 10 )
                dfStartX = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 20 )
                dfStartY = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 11 )
                dfEndX = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 21 )
                dfEndY = CPLAtof(szLineBuf);
            else
                break;

            OGRLineString *poLS = new OGRLineString();

            poLS->addPoint( dfStartX, dfStartY );
            poLS->addPoint( dfEndX, dfEndY );

            poGC->addGeometryDirectly( poLS );
        }
/* -------------------------------------------------------------------- */
/*      Process a circular arc.                                         */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_CIRCULAR_ARC )
        {
            double dfCenterX;
            double dfCenterY;
            double dfRadius;
            double dfStartAngle;
            double dfEndAngle;
            int    bCounterClockwise = FALSE;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 10 )
                dfCenterX = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 20 )
                dfCenterY = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 40 )
                dfRadius = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 50 )
                dfStartAngle = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 51 )
                dfEndAngle = CPLAtof(szLineBuf);
            else
                break;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 73 )
                bCounterClockwise = atoi(szLineBuf);
            else if (nCode >= 0)
                poDS->UnreadValue();

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;
            if( bCounterClockwise )
            {
                dfStartAngle *= -1; 
                dfEndAngle *= -1; 
            }

            OGRGeometry *poArc = OGRGeometryFactory::approximateArcAngles( 
                dfCenterX, dfCenterY, 0.0,
                dfRadius, dfRadius, 0.0,
                dfStartAngle, dfEndAngle, 0.0 );

            poArc->flattenTo2D();

            poGC->addGeometryDirectly( poArc );
        }

/* -------------------------------------------------------------------- */
/*      Process an elliptical arc.                                      */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_ELLIPTIC_ARC )
        {
            double dfCenterX;
            double dfCenterY;
            double dfMajorRadius, dfMinorRadius;
            double dfMajorX, dfMajorY;
            double dfStartAngle;
            double dfEndAngle;
            double dfRotation;
            double dfRatio;
            int    bCounterClockwise = FALSE;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 10 )
                dfCenterX = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 20 )
                dfCenterY = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 11 )
                dfMajorX = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 21 )
                dfMajorY = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 40 )
                dfRatio = CPLAtof(szLineBuf) / 100.0;
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 50 )
                dfStartAngle = CPLAtof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 51 )
                dfEndAngle = CPLAtof(szLineBuf);
            else
                break;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 73 )
                bCounterClockwise = atoi(szLineBuf);
            else if (nCode >= 0)
                poDS->UnreadValue();

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;
            if( bCounterClockwise )
            {
                dfStartAngle *= -1; 
                dfEndAngle *= -1; 
            }

            dfMajorRadius = sqrt( dfMajorX * dfMajorX + dfMajorY * dfMajorY );
            dfMinorRadius = dfMajorRadius * dfRatio;

            dfRotation = -1 * atan2( dfMajorY, dfMajorX ) * 180 / PI;

            OGRGeometry *poArc = OGRGeometryFactory::approximateArcAngles( 
                dfCenterX, dfCenterY, 0.0,
                dfMajorRadius, dfMinorRadius, dfRotation,
                dfStartAngle, dfEndAngle, 0.0 );

            poArc->flattenTo2D();

            poGC->addGeometryDirectly( poArc );
        }
        else
        {
            CPLDebug( "DXF", "Unsupported HATCH boundary line type:%d",
                      nEdgeType );
            return OGRERR_UNSUPPORTED_OPERATION;
        }
    }

/* -------------------------------------------------------------------- */
/*      Skip through source boundary objects if present.                */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 97 )
    {
        if (nCode < 0)
            return OGRERR_FAILURE;
        poDS->UnreadValue();
    }
    else
    {
        int iObj, nObjCount = atoi(szLineBuf);

        for( iObj = 0; iObj < nObjCount; iObj++ )
        {
            if (poDS->ReadValue( szLineBuf, sizeof(szLineBuf) ) < 0)
                return OGRERR_FAILURE;
        }
    }

    return OGRERR_NONE;
}
Пример #30
0
OGRFeature *OGRGmtLayer::GetNextRawFeature()

{
#if 0
    int bMultiVertex =
        poFeatureDefn->GetGeomType() != wkbPoint
        && poFeatureDefn->GetGeomType() != wkbUnknown;
#endif
    CPLString osFieldData;
    OGRGeometry *poGeom = NULL;

/* -------------------------------------------------------------------- */
/*      Read lines associated with this feature.                        */
/* -------------------------------------------------------------------- */
    for( ; true; ReadLine() )
    {
        if( osLine.length() == 0 )
            break;

        if( osLine[0] == '>' )
        {
            if( poGeom != NULL
                && wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon )
            {
                OGRMultiPolygon *poMP = (OGRMultiPolygon *) poGeom;
                if( ScanAheadForHole() )
                {
                    // Add a hole to the current polygon.
                    ((OGRPolygon *) poMP->getGeometryRef(
                        poMP->getNumGeometries()-1 ))->
                        addRingDirectly( new OGRLinearRing() );
                }
                else if( !NextIsFeature() )
                {
                    OGRPolygon *poPoly = new OGRPolygon();

                    poPoly->addRingDirectly( new OGRLinearRing() );

                    poMP->addGeometryDirectly( poPoly );
                }
                else
                    break; /* done geometry */
            }
            else if( poGeom != NULL
                     && wkbFlatten(poGeom->getGeometryType()) == wkbPolygon)
            {
                if( ScanAheadForHole() )
                    ((OGRPolygon *)poGeom)->
                        addRingDirectly( new OGRLinearRing() );
                else
                    break; /* done geometry */
            }
            else if( poGeom != NULL
                     && (wkbFlatten(poGeom->getGeometryType())
                         == wkbMultiLineString)
                     && !NextIsFeature() )
            {
                ((OGRMultiLineString *) poGeom)->
                    addGeometryDirectly( new OGRLineString() );
            }
            else if( poGeom != NULL )
            {
                break;
            }
            else if( poFeatureDefn->GetGeomType() == wkbUnknown )
            {
                poFeatureDefn->SetGeomType( wkbLineString );
                /* bMultiVertex = TRUE; */
            }
        }
        else if( osLine[0] == '#' )
        {
            for( int i = 0;
                 papszKeyedValues != NULL && papszKeyedValues[i] != NULL;
                 i++ )
            {
                if( papszKeyedValues[i][0] == 'D' )
                    osFieldData = papszKeyedValues[i] + 1;
            }
        }
        else
        {
            // Parse point line.
            double dfX;
            double dfY;
            double dfZ = 0.0;
            const int nDim
                = CPLsscanf( osLine, "%lf %lf %lf", &dfX, &dfY, &dfZ );

            if( nDim >= 2 )
            {
                if( poGeom == NULL )
                {
                    switch( poFeatureDefn->GetGeomType() )
                    {
                      case wkbLineString:
                        poGeom = new OGRLineString();
                        break;

                      case wkbPolygon:
                        poGeom = new OGRPolygon();
                        reinterpret_cast<OGRPolygon *>(poGeom)->addRingDirectly(
                            new OGRLinearRing() );
                        break;

                      case wkbMultiPolygon:
                      {
                          OGRPolygon *poPoly = new OGRPolygon();
                          poPoly->addRingDirectly( new OGRLinearRing() );

                          poGeom = new OGRMultiPolygon();
                          reinterpret_cast<OGRMultiPolygon *>(poGeom)->
                              addGeometryDirectly( poPoly );
                      }
                      break;

                      case wkbMultiPoint:
                        poGeom = new OGRMultiPoint();
                        break;

                      case wkbMultiLineString:
                        poGeom = new OGRMultiLineString();
                        reinterpret_cast<OGRMultiLineString *>(poGeom)->
                            addGeometryDirectly(new OGRLineString() );
                        break;

                      case wkbPoint:
                      case wkbUnknown:
                      default:
                        poGeom = new OGRPoint();
                        break;
                    }

                }

                switch( wkbFlatten(poGeom->getGeometryType()) )
                {
                  case wkbPoint:
                    reinterpret_cast<OGRPoint *>(poGeom)->setX( dfX );
                    reinterpret_cast<OGRPoint *>(poGeom)->setY( dfY );
                    if( nDim == 3 )
                        reinterpret_cast<OGRPoint *>(poGeom)->setZ( dfZ );
                    break;

                  case wkbLineString:
                    if( nDim == 3 )
                        reinterpret_cast<OGRLineString *>(poGeom)->
                            addPoint( dfX, dfY, dfZ);
                    else
                        reinterpret_cast<OGRLineString *>(poGeom)->
                            addPoint( dfX, dfY );
                    break;

                  case wkbPolygon:
                  case wkbMultiPolygon:
                  {
                      OGRPolygon *poPoly = NULL;

                      if( wkbFlatten(poGeom->getGeometryType())
                          == wkbMultiPolygon )
                      {
                          OGRMultiPolygon *poMP = (OGRMultiPolygon *) poGeom;
                          poPoly = (OGRPolygon*) poMP->getGeometryRef(
                              poMP->getNumGeometries() - 1 );
                      }
                      else
                          poPoly = reinterpret_cast<OGRPolygon *>(poGeom);

                      OGRLinearRing *poRing = NULL;
                      if( poPoly->getNumInteriorRings() == 0 )
                          poRing = poPoly->getExteriorRing();
                      else
                          poRing = poPoly->getInteriorRing(
                              poPoly->getNumInteriorRings()-1 );

                      if( nDim == 3 )
                          poRing->addPoint( dfX, dfY, dfZ );
                      else
                          poRing->addPoint( dfX, dfY );
                  }
                  break;

                  case wkbMultiLineString:
                  {
                      OGRMultiLineString *poML = (OGRMultiLineString *) poGeom;
                      OGRLineString *poLine = reinterpret_cast<OGRLineString *>(
                          poML->getGeometryRef( poML->getNumGeometries() -1 ) );

                      if( nDim == 3 )
                          poLine->addPoint( dfX, dfY, dfZ );
                      else
                          poLine->addPoint( dfX, dfY );
                  }
                  break;

                  default:
                    CPLAssert( FALSE );
                }
            }
        }

        if( poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint )
        {
            ReadLine();
            break;
        }
    }

    if( poGeom == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create feature.                                                 */
/* -------------------------------------------------------------------- */
    OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
    poGeom->assignSpatialReference(poSRS);
    poFeature->SetGeometryDirectly( poGeom );
    poFeature->SetFID( iNextFID++ );

/* -------------------------------------------------------------------- */
/*      Process field values.                                           */
/* -------------------------------------------------------------------- */
    char **papszFD = CSLTokenizeStringComplex( osFieldData, "|", TRUE, TRUE );

    for( int iField = 0; papszFD != NULL && papszFD[iField] != NULL; iField++ )
    {
        if( iField >= poFeatureDefn->GetFieldCount() )
            break;

        poFeature->SetField( iField, papszFD[iField] );
    }

    CSLDestroy( papszFD );

    m_nFeaturesRead++;

    return poFeature;
}