Example #1
0
void writeSQL(Site_2 site, PointList polygon, char* outdir)
{
  std::cout << "INSERT INTO " << outdir << " (geom, id) VALUES (";
  std::cout << "'POLYGON ((";
  for (int i = 0; i < polygon.size(); i++) {
    Point_2 p = polygon.at(i);
    std::cout << p.x() << " " << p.y();
    if (i < polygon.size() - 1) {
      std::cout << ", ";
    }
  }
  std::cout << "))', " << site.id() << ");" << std::endl;
}
void CSVPointListExporter::exportFromDataBase()
{
    if(!QFile::exists(sourseDataBaseFile_))
    {
        qWarning() << sourseDataBaseFile_ << "not exists";
        return;
    }

    SqlPointListReader reader(sourseDataBaseFile_, sourseTableName_);

    if(!reader.open())
    {
        qWarning() << sourseDataBaseFile_ << "not open";
        return;
    }

    QFile targetFile(targetFileName_);
    if(!targetFile.open(QFile::WriteOnly | QIODevice::Text))
    {
        qWarning() << targetFileName_ << "can't open for writing";
    }

    QTextStream targetFileStream(&targetFile);
    const IDList idList = reader.readAllItems();

    for(int i = 0; i < idList.count(); i++)
    {
        const ID& id = idList.at(i);
        const PointList pointList = reader.read(id);
        for(int j = 0; j < pointList.count(); j++)
        {
            const Point& point = pointList.at(j);
            targetFileStream << pointList.id() << ";" << point;

            const bool isLast = ((i + 1) == idList.count())
                    && ((j + 1) == pointList.count());

            if(!isLast)
            {
                targetFileStream << '\n';
            }
        }
    }

    targetFile.flush();
    targetFile.close();
}
Example #3
0
void writeGeoJSON(Site_2 site, PointList polygon, char* outdir)
{
  // open an output file for storing the WKT
  std::stringstream s;
  s << outdir << "/" << site.id() << ".geojson";
  std::string polygonFileName = s.str();
  std::cerr << "filename: " << polygonFileName << std::endl;
  std::ofstream file;
  file.open(polygonFileName.c_str());

  // write data
  file << "{\"type\":\"Polygon\",\"coordinates\":[[";
  for (int i = 0; i < polygon.size(); i++) {
    Point_2 p = polygon.at(i);
    file << "[" << p.x() << ", " << p.y() << "]";
    if (i < polygon.size() - 1) {
      file << ", ";
    }
  }
  file << "]]}";
  file.close();
}
Example #4
0
void writeWKT(Site_2 site, PointList polygon, char* outdir)
{
  // open an output file for storing the WKT
  std::stringstream s;
  s << outdir << "/" << site.id() << ".wkt";
  std::string polygonFileName = s.str();
  std::cerr << "filename: " << polygonFileName << std::endl;
  std::ofstream file;
  file.open(polygonFileName.c_str());

  // write WKT file
  file << "POLYGON ((";
  for (int i = 0; i < polygon.size(); i++) {
    Point_2 p = polygon.at(i);
    file << p.x() << " " << p.y();
    if (i < polygon.size() - 1) {
      file << ", ";
    }
  }
  file << "))";
  file.close();
}
Example #5
0
int main(int argc , char* argv[])
{
  if (argc < 7) {
    std::cerr << "usage: test <input file> <output folder> "
      "<format (wkt | geojson | sql)> <weight city> <weight town> <weight village>" << std::endl;
    exit(1);
  }

  char* input = argv[1];
  char* outdir = argv[2];
  char* format = argv[3];

  char* swc = argv[4];
  char* swt = argv[5];
  char* swv = argv[6];

  std::ifstream ifs(input);
  assert( ifs );

  double wc, wt, wv;
  std::istringstream stmc, stmt, stmv;
  stmc.str(swc);
  stmc >> wc;
  stmt.str(swt);
  stmt >> wt;
  stmv.str(swv);
  stmv >> wv;

  std::cerr << "using weights: city: " << wc << ", town: " << wt << ", village: " << wv << std::endl;

  /*
   * prepare data
   */

  // we use a ScalingFactor(SF) here to stretch input values at the
  // beginning, and divide by SF in the end. This is used because the
  // point-generation of the hyperbola class is using some arbitrary
  // internal decision thresholds to decide how many points to generate for
  // a certain part of the curve. Rule of thumb is: the higher SF the more
  // detail is used in approximation of the hyperbolas.
  double SF = 4000;

  // read in sites from input file
  SiteList sites = readSites(ifs, SF, wc, wt, wv);

  printSites(sites);

  // calculate bounding box of all input sites (and extend it a little).
  // Extension is important, because we later add artificial sites which are
  // actually mirrored on the bounds of this rectangle. If we did not extend
  // some points would lie on the boundary of the bounding box and so would
  // their artificial clones. This would complicate the whole stuff a lot :)
  Iso_rectangle_2 crect = extend(boundingBox(sites), 0.1*SF);
  std::cerr << "rect: " << crect << std::endl;

  // a number of artificial sites
  SiteList artificialSites = createArtificialSites(sites, crect);

  /*
   * create Apollonius graph
   */

  Apollonius_graph ag;

  SiteList::iterator itr;
  // add all original sites to the apollonius graph
  for (itr = sites.begin(); itr != sites.end(); ++itr) {
    Site_2 site = *itr;
    ag.insert(site);
  }
  // add all artificial sites to the apollonius graph
  for (itr = artificialSites.begin(); itr != artificialSites.end(); ++itr) {
    Site_2 site = *itr;
    ag.insert(site);
  }

  // validate the Apollonius graph
  assert( ag.is_valid(true, 1) );
  std::cerr << std::endl;

  /*
   * create polygons from cells
   */

  // we want an identifier for each vertex within the iteration.
  // this is a loop iteration counter
  int vertexIndex = 0;

  // for each vertex in the apollonius graph (this are the sites)
  for (All_vertices_iterator viter = ag.all_vertices_begin ();
      viter != ag.all_vertices_end(); ++viter) {
    // get the corresponding site
    Site_2 site = viter->site();
    Point_2 point = site.point();
    // ignore artifical sites, detect them by their position
    if (!CGAL::do_intersect(crect, point)) {
      continue;
    }
    std::cerr << "vertex " << ++vertexIndex << std::endl;

    // we than circulate all incident edges. By obtaining the respective
    // dual of each edge, we get access to the objects forming the boundary
    // of each voronoi cell in a proper order.
    Edge_circulator ecirc = ag.incident_edges(viter), done(ecirc);
    // this is where we store the polylines
    std::vector<PointList> polylines;
    // for each incident edge
    do {
      // the program may fail in certain situations without this test.
      // acutally !is_infinite(edge) is a precondition in ag.dual(edge).
      if (ag.is_infinite(*ecirc)) {
        continue;
      }
      // NOTE: for this to work, we had to make public the dual function in ApolloniusGraph
      // change line 542 in "Apollonius_graph_2.h" from "private:" to "public:"
      Object_2 o = ag.dual(*ecirc);
      handleDual(o, crect, polylines);
    } while(++ecirc != done);

    PointList polygon = buildPolygon(site, polylines);
    for (int i = 0; i < polygon.size(); i++) {
      Point_2& p = polygon.at(i);
      p = Point_2(p.x()/SF, p.y()/SF);
    }
    if(std::string(format) == "geojson") {
      writeGeoJSON(site, polygon, outdir);
    } else if(std::string(format) == "sql") {
      writeSQL(site, polygon, outdir);
    } else {
      writeWKT(site, polygon, outdir);
    }

    // check each point
    for (int i = 0; i < polygon.size(); i++) {
      Point_2 p = polygon.at(i);
      if (p.x() > crect.xmax()/SF || p.x() < crect.xmin()/SF || p.y() > crect.ymax()/SF || p.y() < crect.ymin()/SF) {
        std::cerr << "out of bounds" << std::endl;
      }
    }
  }
}