void HiJitCube::computePoly() { // Compute sample and line coordinates in the focal plane int samp0,sampN; if (originst) { samp0=jdata.fpSamp0 + jdata.sampOffset; sampN=samp0 + npSamps[jdata.cpmmNumber] - 1; } else { samp0=jdata.fpSamp0 + jdata.sampOffset; sampN=samp0 + Samples() - 1; } int line0(jdata.fpLine0 + jdata.lineOffset), lineN(line0 + Lines() - 1); // Allocate a new coordinate sequence and define it geos::geom::CoordinateSequence *pts = new geos::geom::CoordinateArraySequence(); pts->add(geos::geom::Coordinate(samp0, lineN)); pts->add(geos::geom::Coordinate(sampN, lineN)); pts->add(geos::geom::Coordinate(sampN, line0)); pts->add(geos::geom::Coordinate(samp0, line0)); pts->add(geos::geom::Coordinate(samp0, lineN)); // Make this reentrant and delete previous one if it exists and get the // new one delete fpGeom; fpGeom = geosFactory.createPolygon(geosFactory.createLinearRing(pts), 0); return; }
/*** * Union linestrings to multilinestring and insert them into table * relations. */ void create_relation(const osmium::Relation &relation, const osmium::object_id_type relation_id, bool &contains_nowaterway_ways, vector<geos::geom::Geometry *> *linestrings) { if (!(linestrings->size())) { return; } const geos::geom::GeometryFactory geom_factory = geos::geom::GeometryFactory(); geos::geom::GeometryCollection *geom_collection = nullptr; try { geom_collection = geom_factory.createGeometryCollection( linestrings); } catch (...) { cerr << "Failed to create geometry collection at relation: " << relation_id << endl; delete linestrings; return; } geos::geom::Geometry *geos_geom = nullptr; try { geos_geom = geom_collection->Union().release(); } catch (...) { cerr << "Failed to union linestrings at relation: " << relation_id << endl; delete geom_collection; return; } OGRGeometry *ogr_multilinestring = nullptr; ogr_multilinestring = geos2ogr(geos_geom); if (!strcmp(ogr_multilinestring->getGeometryName(),"LINESTRING")) { try { ogr_multilinestring = OGRGeometryFactory::forceToMultiLineString( ogr_multilinestring); } catch (...) { delete geom_collection; delete geos_geom; return; } } try { ds.insert_relation_feature(ogr_multilinestring, relation, contains_nowaterway_ways); } catch (osmium::geometry_error&) { OGRGeometryFactory::destroyGeometry(ogr_multilinestring); cerr << "Inserting to table failed for relation: " << relation_id << endl; } catch (...) { OGRGeometryFactory::destroyGeometry(ogr_multilinestring); cerr << "Inserting to table failed for relation: " << relation_id << endl; cerr << " Unexpected error" << endl; } delete geom_collection; delete geos_geom; OGRGeometryFactory::destroyGeometry(ogr_multilinestring); }
GeomPtr getGeometry(SegStrVct& vct) { GeomVct* lines = new GeomVct; for(SegStrVct::size_type i = 0, n = vct.size(); i < n; ++i) { SegmentString* ss = vct[i]; lines->push_back(gf_->createLineString(*(ss->getCoordinates()))); } return GeomPtr(gf_->createMultiLineString(lines)); }
point_type make_point(const osmium::geom::Coordinates& xy) const { try { return point_type(m_geos_factory.createPoint(geos::geom::Coordinate(xy.x, xy.y))); } catch (geos::util::GEOSException&) { THROW(osmium::geos_geometry_error()); } }
void multipolygon_inner_ring_start() { try { m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast<std::size_t>(0), 2)); } catch (const geos::util::GEOSException& e) { THROW(osmium::geos_geometry_error(e.what())); } }
void linestring_start() { try { m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2)); } catch (geos::util::GEOSException& e) { THROW(osmium::geos_geometry_error(e.what())); } }
void multipolygon_inner_ring_finish() { try { m_rings.emplace_back(m_geos_factory->createLinearRing(m_coordinate_sequence.release())); } catch (const geos::util::GEOSException& e) { THROW(osmium::geos_geometry_error(e.what())); } }
linestring_type linestring_finish(std::size_t /* num_points */) { try { return linestring_type{m_geos_factory->createLineString(m_coordinate_sequence.release())}; } catch (const geos::util::GEOSException& e) { THROW(osmium::geos_geometry_error(e.what())); } }
void multipolygon_outer_ring_start() { try { m_coordinate_sequence.reset(m_geos_factory.getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2)); } catch (geos::util::GEOSException&) { THROW(osmium::geos_geometry_error()); } }
point_type make_point(const osmium::geom::Coordinates& xy) const { try { return point_type{m_geos_factory->createPoint(geos::geom::Coordinate{xy.x, xy.y})}; } catch (const geos::util::GEOSException& e) { THROW(osmium::geos_geometry_error(e.what())); } }
linestring_type linestring_finish(size_t /* num_points */) { try { return linestring_type(m_geos_factory.createLineString(m_coordinate_sequence.release())); } catch (geos::util::GEOSException&) { THROW(osmium::geos_geometry_error()); } }
~test_preparedgeometryfactory_data() { // FREE MEMORY per test case prep::PreparedGeometryFactory::destroy(pg_); factory_.destroyGeometry(g_); pg_ = 0; g_ = 0; }
test_polygon_data() : pm_(1), factory_(&pm_, 0), reader_(&factory_), empty_poly_(factory_.createPolygon()), poly_size_(7) { // Create non-empty LinearRing GeometryPtr geo = 0; geo = reader_.read("POLYGON((0 10, 5 5, 10 5, 15 10, 10 15, 5 15, 0 10))"); poly_ = static_cast<PolygonPtr>(geo); }
void create_discs(geos::geom::GeometryFactory& gf, int num, double radius, std::vector<geos::geom::Polygon*>* g) { for (int i = 0; i < num; ++i) { for (int j = 0; j < num; ++j) { std::auto_ptr<geos::geom::Point> pt( gf.createPoint(geos::geom::Coordinate(i, j))); g->push_back(dynamic_cast<geos::geom::Polygon*>(pt->buffer(radius))); } } }
multipolygon_type multipolygon_finish() { try { auto polygons = new std::vector<geos::geom::Geometry*>; std::transform(m_polygons.begin(), m_polygons.end(), std::back_inserter(*polygons), [](std::unique_ptr<geos::geom::Polygon>& p) { return p.release(); }); m_polygons.clear(); return multipolygon_type{m_geos_factory->createMultiPolygon(polygons)}; } catch (const geos::util::GEOSException& e) { THROW(osmium::geos_geometry_error(e.what())); } }
void multipolygon_polygon_finish() { try { assert(!m_rings.empty()); auto inner_rings = new std::vector<geos::geom::Geometry*>; std::transform(std::next(m_rings.begin(), 1), m_rings.end(), std::back_inserter(*inner_rings), [](std::unique_ptr<geos::geom::LinearRing>& r) { return r.release(); }); m_polygons.emplace_back(m_geos_factory->createPolygon(m_rings[0].release(), inner_rings)); m_rings.clear(); } catch (const geos::util::GEOSException& e) { THROW(osmium::geos_geometry_error(e.what())); } }
bool pointsWithinDistance(vector<Coordinate>& coords, double dist) { // we expect some numerical instability here // OffsetPointGenerator could produce points // at *slightly* farther locations then // requested // dist *= 1.0000001; for (size_t i=0, n=coords.size(); i<n; ++i) { const Coordinate& c = coords[i]; auto_ptr<Geometry> pg(gf.createPoint(c)); double rdist = g->distance(pg.get()); if ( rdist > dist ) { return false; } } return true; }
~test_linestring_data() { factory_.destroyGeometry(empty_line_); empty_line_ = 0; }
namespace Isis { static geos::geom::GeometryFactory geosFactory; bool HiJitCube::naifLoaded = false; int npSamp0[] = {0,1971,3964,5963,7970,7971,7971,9975,9976,9976,11981,13986,15984,17982}; int npSamps[] = {2021,2043,2048,2052,2055,2053,2053,2053,2054,2055,2051,2049,2043,2018}; bool sampinit=false; bool originst; /** * @brief Default constructor with no cube */ HiJitCube::HiJitCube() { initLocal(); } /** * @brief Constructor with file to open */ HiJitCube::HiJitCube(const std::string &filename) { initLocal(); OpenCube(filename); } /** * @brief Constructor with file to open and potential shift applied */ HiJitCube::HiJitCube(const std::string &filename, PvlObject &shift) { initLocal(); OpenCube(filename, shift); } /** * @brief Destructor */ HiJitCube::~HiJitCube() { delete fpGeom; Close(); } void HiJitCube::setSampleOffset(int soff) { jdata.sampOffset = soff; if (IsOpen()) computePoly(); return; } void HiJitCube::setLineOffset(int loff) { jdata.lineOffset = loff; if (IsOpen()) computePoly(); return; } void HiJitCube::OpenCube(const std::string &filename) { Open(filename); Init(); return; } void HiJitCube::OpenCube(const std::string &filename, PvlObject &shift) { OpenCube(filename); // Determine if a shift of the CCD exists in the definitions file if (shift.HasGroup(jdata.ccdName)) { PvlGroup &ccddef = shift.FindGroup(jdata.ccdName, Pvl::Traverse); if (ccddef.HasKeyword("SampleOffset")) { jdata.sampOffset = (int) ccddef["SampleOffset"]; } if (ccddef.HasKeyword("LineOffset")) { jdata.lineOffset = (int) ccddef["LineOffset"]; } computePoly(); } return; } double HiJitCube::getLineTime(double line) const { return (((line-1.0) * jdata.linerate) + jdata.obsStartTime); } void HiJitCube::Compatable(HiJitCube &cube) throw (iException &) { JitInfo other = cube.GetInfo(); if (jdata.summing != other.summing) { ostringstream msg; msg << "Summing mode (" << jdata.summing << ") in file " << Filename() << " is not equal to summing mode (" << other.summing << ") in file " << cube.Filename() << endl; throw iException::Message(iException::User,msg.str(),_FILEINFO_); } return; } bool HiJitCube::intersects(const HiJitCube &cube) const { return (fpGeom->intersects(cube.Poly())); } bool HiJitCube::overlap(const HiJitCube &cube, Corners &ovlCorners) { geos::geom::Geometry *ovl = fpGeom->intersection(cube.Poly()); // cout << "Overlap: " << ovl->toString() << std::endl; ovlCorners = FocalPlaneToImage(getCorners(*ovl)); delete ovl; return (ovlCorners.good); } void HiJitCube::loadNaifTiming( ) { if (!naifLoaded) { // Load the NAIF kernels to determine timing data Isis::Filename leapseconds("$base/kernels/lsk/naif????.tls"); leapseconds.HighestVersion(); Isis::Filename sclk("$mro/kernels/sclk/MRO_SCLKSCET.?????.65536.tsc"); sclk.HighestVersion(); // Load the kernels string lsk = leapseconds.Expanded(); string sClock = sclk.Expanded(); furnsh_c(lsk.c_str()); furnsh_c(sClock.c_str()); // Ensure it is loaded only once naifLoaded = true; } return; } void HiJitCube::computeStartTime() { loadNaifTiming(); // Compute the unbinned and binned linerates in seconds jdata.unBinnedRate = ((Instrument::LINE_TIME_PRE_OFFSET + (jdata.dltCount/Instrument::HIRISE_CLOCK_SUBTICK_MICROS)) / 1000000.0); jdata.linerate = jdata.unBinnedRate * ((double) jdata.summing); if (!jdata.scStartTime.empty()) { string scStartTimeString = jdata.scStartTime; scs2e_c (-74999,scStartTimeString.c_str(),&jdata.obsStartTime); // Adjust the start time so that it is the effective time for // the first line in the image file jdata.obsStartTime -= (jdata.unBinnedRate * (((double(jdata.tdiMode/2.0) - 0.5)))); // Effective observation // time for all the TDI lines used for the // first line before doing binning jdata.obsStartTime += (jdata.unBinnedRate * (((double) jdata.summing/2.0) - 0.5)); } return; } void HiJitCube::initLocal() { jdata.filename = "_none_"; jdata.productId = "__undetermined__"; jdata.lines = 0; jdata.samples = 0; jdata.sampOffset = 0; jdata.lineOffset = 0; jdata.tdiMode = 0; jdata.summing = 0; jdata.channelNumber = 0; jdata.cpmmNumber = 0; jdata.ccdName ="_unknown_"; jdata.dltCount = 0.0; jdata.UTCStartTime = ""; jdata.scStartTime = ""; jdata.obsStartTime = 0.0; jdata.unBinnedRate = 0.0; jdata.linerate = 0.0; jdata.fpSamp0 = 0; jdata.fpLine0 = 0; jdata.pixpitch = 0.0; fpGeom = 0; } void HiJitCube::Init() throw (iException &) { // Get required keywords from instrument group Pvl *label(Label()); Isis::PvlGroup inst; Isis::PvlGroup idinst; jdata.filename = Filename(); Isis::PvlGroup &archive = label->FindGroup ("Archive",Isis::Pvl::Traverse); jdata.productId = (string) archive["ProductId"]; jdata.lines = Lines(); if (label->FindObject("IsisCube").HasGroup("OriginalInstrument")) { inst = label->FindGroup ("OriginalInstrument",Isis::Pvl::Traverse); originst = true; } else { inst = label->FindGroup ("Instrument",Isis::Pvl::Traverse); originst = false; } jdata.tdiMode = inst["Tdi"]; jdata.summing = inst["Summing"]; if (label->FindObject("IsisCube").HasGroup("Instrument") && originst) { idinst = label->FindGroup ("Instrument",Isis::Pvl::Traverse); jdata.pixpitch = idinst["PixelPitch"]; jdata.summing = (int) (jdata.pixpitch/.012); } if (originst && jdata.summing != 1 && !sampinit) { for (int i=0; i<14; i++) { npSamps[i] = (int) (npSamps[i]/(float)jdata.summing + 0.5); npSamp0[i] = (int) (npSamp0[i]/(float)jdata.summing + 0.5); } sampinit = true; } jdata.channelNumber = inst["ChannelNumber"]; jdata.cpmmNumber = inst["CpmmNumber"]; if (originst) { jdata.samples = npSamps[jdata.cpmmNumber]; } else { jdata.samples = Samples(); } jdata.ccdName = Instrument::CCD_NAMES[jdata.cpmmNumber]; jdata.dltCount = inst["DeltaLineTimerCount"]; jdata.UTCStartTime = (string) inst["StartTime"]; jdata.scStartTime = (string) inst["SpacecraftClockStartCount"]; try { if (originst) { jdata.fpSamp0 = npSamp0[jdata.cpmmNumber]; } else { jdata.fpSamp0 = Instrument::focal_plane_x_offset(jdata.cpmmNumber, jdata.summing); } } catch (Exception hiExc) { ostringstream msg; msg << "Summing mode (" << jdata.summing << ") is illegal (must be > 0) or CPMM number (" << jdata.cpmmNumber << ") is invalid in file " << Filename() << endl; throw iException::Message(iException::User,msg.str(),_FILEINFO_); } // It is assumed all images start at the line location in the focal plane jdata.fpLine0 = 0; // Validate channel number and adjust starting sample if ((jdata.channelNumber > 2) || (jdata.channelNumber < 0)) { ostringstream msg; msg << "Channel number (" << jdata.channelNumber << ") is invalid (must be 0, 1 or 2) in file " << Filename() << endl; throw iException::Message(iException::User,msg.str(),_FILEINFO_); } else { if (originst) { if (jdata.channelNumber == 0) jdata.fpSamp0 += npSamps[jdata.cpmmNumber]; } else { if (jdata.channelNumber == 0) jdata.fpSamp0 += Samples(); } } // Determine starting time of image and compute the binning rates computeStartTime(); // Compute the focal plane polygon for this image computePoly(); return; } int HiJitCube::getBinModeIndex(int summing) const throw (iException &) { for (unsigned int i = 0 ; i < Instrument::TOTAL_BINNING_FACTORS ; i++) { int binFactor = Instrument::BINNING_FACTORS[i]; if (binFactor == summing) return (i); } ostringstream msg; msg << "Invalid summing mode (" << summing << ") for file " << Filename() << std::endl; throw iException::Message(iException::User,msg.str(),_FILEINFO_); } void HiJitCube::computePoly() { // Compute sample and line coordinates in the focal plane int samp0,sampN; if (originst) { samp0=jdata.fpSamp0 + jdata.sampOffset; sampN=samp0 + npSamps[jdata.cpmmNumber] - 1; } else { samp0=jdata.fpSamp0 + jdata.sampOffset; sampN=samp0 + Samples() - 1; } int line0(jdata.fpLine0 + jdata.lineOffset), lineN(line0 + Lines() - 1); // Allocate a new coordinate sequence and define it geos::geom::CoordinateSequence *pts = new geos::geom::CoordinateArraySequence(); pts->add(geos::geom::Coordinate(samp0, lineN)); pts->add(geos::geom::Coordinate(sampN, lineN)); pts->add(geos::geom::Coordinate(sampN, line0)); pts->add(geos::geom::Coordinate(samp0, line0)); pts->add(geos::geom::Coordinate(samp0, lineN)); // Make this reentrant and delete previous one if it exists and get the // new one delete fpGeom; fpGeom = geosFactory.createPolygon(geosFactory.createLinearRing(pts), 0); return; } HiJitCube::Corners HiJitCube::FocalPlaneToImage(const Corners &fp) const { Corners image; if (fp.good) { double samp0; // Compute sample and line coordinates in the focal plane if (originst) { samp0 = 0; } else { samp0 = jdata.fpSamp0 + jdata.sampOffset; } double line0(jdata.fpLine0 + jdata.lineOffset); image.topLeft.sample = fp.topLeft.sample - samp0 + 1.0; image.topLeft.line = fp.topLeft.line - line0 + 1.0; image.lowerRight.sample = fp.lowerRight.sample - samp0 + 1.0; image.lowerRight.line = fp.lowerRight.line - line0 + 1.0; image.good = true; } return (image); } HiJitCube::Corners HiJitCube::getCorners(const geos::geom::Geometry &poly) const { Corners corners; if ((poly.isValid()) && (!poly.isEmpty())) { // Get the coordinate list geos::geom::CoordinateSequence *clist = poly.getCoordinates(); const geos::geom::Coordinate *minpt = clist->minCoordinate(); // cout << "MinPoint: " << minpt->x << ", " << minpt->y << std::endl; geos::geom::Coordinate maxpt(clist->getAt(0)); for (unsigned int i = 1 ; i < clist->getSize() ; i++) { geos::geom::Coordinate pt = clist->getAt(i); if ((pt.x >= maxpt.x) && (pt.y >= maxpt.y)) maxpt = pt; } // cout << "MaxPoint: " << maxpt.x << ", " << maxpt.y << std::endl; corners.topLeft.sample = minpt->x; corners.topLeft.line = minpt->y; corners.lowerRight.sample = maxpt.x; corners.lowerRight.line = maxpt.y; corners.good = true; delete clist; } return (corners); } }
~test_polygon_data() { // FREE MEMORY factory_.destroyGeometry(poly_); }
test_linestring_data() : pm_(1000), factory_(&pm_, 0), reader_(&factory_), empty_line_(factory_.createLineString(new geos::geom::CoordinateArraySequence())) { assert(0 != empty_line_); }