Skip to content

Commit

Permalink
update util
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickbr committed Oct 5, 2023
1 parent 426077e commit 556c6d2
Show file tree
Hide file tree
Showing 11 changed files with 226 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/octi/Octilinearizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ Score Octilinearizer::draw(const CombGraph& cg, const DBox& box,
}
}

size_t bestCore;
size_t bestCore = 0;
double bestScore = std::numeric_limits<double>::infinity();
for (size_t i = 0; i < jobs; i++) {
if (bestFrIters[i].score() < bestScore) {
Expand Down
6 changes: 6 additions & 0 deletions src/util/String.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@

namespace util {

// _____________________________________________________________________________
inline bool endsWith(const std::string& a, const std::string& suff) {
if (suff.size() > a.size()) return false;
return a.compare(a.length() - suff.length(), suff.length(), suff) == 0;
}

// _____________________________________________________________________________
inline std::string urlDecode(const std::string& encoded) {
std::string decoded;
Expand Down
125 changes: 125 additions & 0 deletions src/util/geo/Geo.h
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,36 @@ inline std::vector<Point<T>> intersection(const Line<T>& l1,
return ret;
}

// _____________________________________________________________________________
template <typename T>
inline Box<T> intersection(const Box<T>& b1, const Box<T>& b2) {
if (!intersects(b1, b2)) return Box<T>();

T llx, lly, urx, ury;

if (b1.getLowerLeft().getX() > b2.getLowerLeft().getX())
llx = b1.getLowerLeft().getX();
else
llx = b2.getLowerLeft().getX();

if (b1.getLowerLeft().getY() > b2.getLowerLeft().getY())
lly = b1.getLowerLeft().getY();
else
lly = b2.getLowerLeft().getY();

if (b1.getUpperRight().getX() < b2.getUpperRight().getX())
urx = b1.getUpperRight().getX();
else
urx = b2.getUpperRight().getX();

if (b1.getUpperRight().getY() < b2.getUpperRight().getY())
ury = b1.getUpperRight().getY();
else
ury = b2.getUpperRight().getY();

return Box<T>{{llx, lly}, {urx, ury}};
}

// _____________________________________________________________________________
template <typename T>
inline bool lineIntersects(T p1x, T p1y, T q1x, T q1y, T p2x, T p2y, T q2x,
Expand Down Expand Up @@ -948,6 +978,7 @@ inline double dist(const Point<T>& p1, const Point<T>& p2) {
template <typename T>
inline Point<T> pointFromWKT(std::string wkt) {
wkt = util::normalizeWhiteSpace(util::trim(wkt));
for (size_t i = 0; i < 6;i++) wkt[i] = toupper(wkt[i]);
if (wkt.rfind("POINT") == 0 || wkt.rfind("MPOINT") == 0) {
size_t b = wkt.find("(") + 1;
size_t e = wkt.find(")", b);
Expand All @@ -965,6 +996,7 @@ inline Point<T> pointFromWKT(std::string wkt) {
template <typename T>
inline Line<T> lineFromWKT(std::string wkt) {
wkt = util::normalizeWhiteSpace(util::trim(wkt));
for (size_t i = 0; i < 11;i++) wkt[i] = toupper(wkt[i]);
if (wkt.rfind("LINESTRING") == 0 || wkt.rfind("MLINESTRING") == 0) {
Line<T> ret;
size_t b = wkt.find("(") + 1;
Expand All @@ -983,6 +1015,96 @@ inline Line<T> lineFromWKT(std::string wkt) {
throw std::runtime_error("Could not parse WKT");
}

// _____________________________________________________________________________
template <typename T>
inline MultiPolygon<T> multiPolygonFromWKT(std::string wkt) {
wkt = util::normalizeWhiteSpace(util::trim(wkt));
for (size_t i = 0; i < 13;i++) wkt[i] = toupper(wkt[i]);
util::replaceAll(wkt, "))", ")!");
util::replaceAll(wkt, ") )", ")!");
if (wkt.rfind("MULTIPOLYGON") == 0 || wkt.rfind("MMULTIPOLYGON") == 0) {
MultiPolygon<T> ret;
size_t b = wkt.find("(") + 1;
size_t e = wkt.rfind(")");
if (b > e) throw std::runtime_error("Could not parse WKT");

auto polyPairs = util::split(wkt.substr(b, e - b), '!');

for (const auto& polyPair : polyPairs) {
size_t b = polyPair.find("(") + 1;
size_t e = polyPair.rfind(")");
auto pairs = util::split(polyPair.substr(b, e - b), ')');

ret.push_back({});

for (size_t i = 0; i < pairs.size(); i++) {
size_t b = pairs[i].find("(") + 1;
size_t e = pairs[i].rfind(")", b);
auto pairsLoc = util::split(pairs[i].substr(b, e - b), ',');

if (i > 0) {
ret.back().getInners().push_back({});
}

for (const auto& p : pairsLoc) {
auto xy = util::split(util::trim(p), ' ');
if (xy.size() < 2) throw std::runtime_error("Could not parse WKT");
double x = atof(xy[0].c_str());
double y = atof(xy[1].c_str());

if (i == 0) {
ret.back().getOuter().push_back({x, y});
} else {
ret.back().getInners().back().push_back({x, y});
}
}
}
}
return ret;
}
throw std::runtime_error("Could not parse WKT");
}

// _____________________________________________________________________________
template <typename T>
inline Polygon<T> polygonFromWKT(std::string wkt) {
wkt = util::normalizeWhiteSpace(util::trim(wkt));
for (size_t i = 0; i < 8;i++) wkt[i] = toupper(wkt[i]);
if (wkt.rfind("POLYGON") == 0 || wkt.rfind("MPOLYGON") == 0) {
Polygon<T> ret;
size_t b = wkt.find("(") + 1;
size_t e = wkt.rfind(")");
if (b > e) throw std::runtime_error("Could not parse WKT");

auto pairs = util::split(wkt.substr(b, e - b), ')');

for (size_t i = 0; i < pairs.size(); i++) {
size_t b = pairs[i].find("(") + 1;
size_t e = pairs[i].rfind(")", b);
auto pairsLoc = util::split(pairs[i].substr(b, e - b), ',');

if (i > 0) {
ret.getInners().push_back({});
}

for (const auto& p : pairsLoc) {
auto xy = util::split(util::trim(p), ' ');
if (xy.size() < 2) throw std::runtime_error("Could not parse WKT");
double x = atof(xy[0].c_str());
double y = atof(xy[1].c_str());

if (i == 0) {
ret.getOuter().push_back({x, y});
} else {
ret.getInners().back().push_back({x, y});
}
}
}
return ret;
}
throw std::runtime_error("Could not parse WKT");
}

// _____________________________________________________________________________
template <typename T>
inline std::string getWKT(const Point<T>& p) {
Expand Down Expand Up @@ -1394,6 +1516,9 @@ inline Polygon<T> buffer(const Polygon<T>& pol, double d, size_t points) {
// _____________________________________________________________________________
template <typename T>
inline Box<T> extendBox(const Box<T>& a, Box<T> b) {
if (a.getLowerLeft().getX() > a.getUpperRight().getX()) return b;
if (a.getLowerLeft().getY() > a.getUpperRight().getY()) return b;

b = extendBox(a.getLowerLeft(), b);
b = extendBox(a.getUpperRight(), b);
return b;
Expand Down
7 changes: 5 additions & 2 deletions src/util/geo/Grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ class Grid {
void get(size_t x, size_t y, std::set<V>* s) const;
void remove(V val);

const std::set<V>& getCell(size_t x, size_t y) const;

void getNeighbors(const V& val, double d, std::set<V>* s) const;
void getCellNeighbors(const V& val, size_t d, std::set<V>* s) const;
void getCellNeighbors(size_t x, size_t y, size_t xPerm, size_t yPerm,
Expand All @@ -105,6 +107,9 @@ class Grid {
size_t getCellXFromX(double lon) const;
size_t getCellYFromY(double lat) const;

Box<T> getBox(size_t x, size_t y) const;
Box<T> getBBox() const { return _bb; };

private:
double _width;
double _height;
Expand All @@ -123,8 +128,6 @@ class Grid {
std::set<V>** _grid;
std::map<V, std::set<std::pair<size_t, size_t> > > _index;
std::set<V> _removed;

Box<T> getBox(size_t x, size_t y) const;
};

#include "util/geo/Grid.tpp"
Expand Down
6 changes: 6 additions & 0 deletions src/util/geo/Grid.tpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ void Grid<V, G, T>::get(size_t x, size_t y, std::set<V>* s) const {
}
}

// _____________________________________________________________________________
template <typename V, template <typename> class G, typename T>
const std::set<V>& Grid<V, G, T>::getCell(size_t x, size_t y) const {
return _grid[x][y];
}

// _____________________________________________________________________________
template <typename V, template <typename> class G, typename T>
void Grid<V, G, T>::remove(V val) {
Expand Down
4 changes: 4 additions & 0 deletions src/util/geo/Polygon.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ class Polygon {
const Line<T>& getOuter() const { return _outer; }
Line<T>& getOuter() { return _outer; }

const std::vector<Line<T>>& getInners() const { return _inners; }
std::vector<Line<T>>& getInners() { return _inners; }

private:
Line<T> _outer;
std::vector<Line<T>> _inners;
};

template <typename T>
Expand Down
15 changes: 10 additions & 5 deletions src/util/geo/output/GeoJsonOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ using namespace geo;
using namespace output;

// _____________________________________________________________________________
GeoJsonOutput::GeoJsonOutput(std::ostream& str) : _wr(&str, 10, true) {
_wr.obj();
_wr.keyVal("type", "FeatureCollection");
_wr.key("features");
_wr.arr();
GeoJsonOutput::GeoJsonOutput(std::ostream& str) : GeoJsonOutput(str, false) {}

// _____________________________________________________________________________
GeoJsonOutput::GeoJsonOutput(std::ostream& str, bool raw) : _wr(&str, 10, true) {
if (!raw) {
_wr.obj();
_wr.keyVal("type", "FeatureCollection");
_wr.key("features");
_wr.arr();
}
}

// _____________________________________________________________________________
Expand Down
7 changes: 7 additions & 0 deletions src/util/geo/output/GeoJsonOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ namespace output {
class GeoJsonOutput {
public:
GeoJsonOutput(std::ostream& str);
GeoJsonOutput(std::ostream& str, bool raw);
GeoJsonOutput(std::ostream& str, json::Val attrs);
~GeoJsonOutput();

template <typename T>
void print(const Point<T>& p, json::Val attrs);

template <typename T>
void print(const MultiPoint<T>& ps, json::Val attrs);

template <typename T>
void print(const Line<T>& l, json::Val attrs);

Expand All @@ -40,6 +44,9 @@ class GeoJsonOutput {
template <typename T>
void printLatLng(const Point<T>& p, json::Val attrs);

template <typename T>
void printLatLng(const MultiPoint<T>& ps, json::Val attrs);

template <typename T>
void printLatLng(const Line<T>& l, json::Val attrs);

Expand Down
57 changes: 52 additions & 5 deletions src/util/geo/output/GeoJsonOutput.tpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,31 @@ void GeoJsonOutput::print(const Point<T>& p, json::Val attrs) {
_wr.close();
}

// _____________________________________________________________________________
template <typename T>
void GeoJsonOutput::print(const MultiPoint<T>& ps, json::Val attrs) {
if (!ps.size()) return;
_wr.obj();
_wr.keyVal("type", "Feature");

_wr.key("geometry");
_wr.obj();
_wr.keyVal("type", "MultiPoint");
_wr.key("coordinates");
_wr.arr();
for (auto p : ps) {
_wr.arr();
_wr.val(p.getX());
_wr.val(p.getY());
_wr.close();
}
_wr.close();
_wr.close();
_wr.key("properties");
_wr.val(attrs);
_wr.close();
}

// _____________________________________________________________________________
template <typename T>
void GeoJsonOutput::print(const Line<T>& line, json::Val attrs) {
Expand Down Expand Up @@ -65,15 +90,27 @@ void GeoJsonOutput::print(const Polygon<T>& poly, json::Val attrs) {
_wr.keyVal("type", "Polygon");
_wr.key("coordinates");
_wr.arr();

_wr.arr();
for (auto p : poly.getOuter()) {
_wr.arr();
_wr.val(p.getX());
_wr.val(p.getY());
_wr.close();
}

_wr.close();

for (const auto& inner : poly.getInners()) {
_wr.arr();
for (auto p : inner) {
_wr.arr();
_wr.val(p.getX());
_wr.val(p.getY());
_wr.close();
}
_wr.close();
}

_wr.close();
_wr.close();
_wr.key("properties");
Expand All @@ -90,16 +127,26 @@ void GeoJsonOutput::print(const MultiPolygon<T>& mpoly, json::Val attrs) {
// _____________________________________________________________________________
template <typename T>
void GeoJsonOutput::printLatLng(const Point<T>& p, json::Val attrs) {
auto projP = util::geo::webMercToLatLng<double>(p.getX(), p.getY());
auto projP = util::geo::webMercToLatLng<T>(p.getX(), p.getY());
print(projP, attrs);
}

// _____________________________________________________________________________
template <typename T>
void GeoJsonOutput::printLatLng(const MultiPoint<T>& ps, json::Val attrs) {
MultiPoint<T> projPs;
for (auto p : ps)
projPs.push_back(util::geo::webMercToLatLng<T>(p.getX(), p.getY()));

print(projPs, attrs);
}

// _____________________________________________________________________________
template <typename T>
void GeoJsonOutput::printLatLng(const Line<T>& line, json::Val attrs) {
Line<T> projL;
for (auto p : line)
projL.push_back(util::geo::webMercToLatLng<double>(p.getX(), p.getY()));
projL.push_back(util::geo::webMercToLatLng<T>(p.getX(), p.getY()));

print(projL, attrs);
}
Expand All @@ -114,8 +161,8 @@ void GeoJsonOutput::printLatLng(const MultiLine<T>& mline, json::Val attrs) {
template <typename T>
void GeoJsonOutput::printLatLng(const Polygon<T>& poly, json::Val attrs) {
Polygon<T> projP;
for (auto p : poly)
projP.push_back(util::geo::webMercToLatLng<double>(p.getX(), p.getY()));
for (auto p : poly.getOuter())
projP.getOuter().push_back(util::geo::webMercToLatLng<T>(p.getX(), p.getY()));

print(projP, attrs);
}
Expand Down

0 comments on commit 556c6d2

Please sign in to comment.