Commit 3f403a81 authored by Victor Brestoiu's avatar Victor Brestoiu

Initial upload.

parent 29b97487
ShapeImport/SFML/cmake/
ShapeImport/SFML/doc/
ShapeImport/SFML/examples/
ShapeImport/SFML/readme.txt
*.vcxproj
*.vcxproj.*
\ No newline at end of file
A quick look over the layout of the streets and the transit routes
Most of the time, the urban area looks like a well organized grid of blocks (Fig.1a) that can be modeled with a simple network of nodes, mathematically called a graph (Fig.1b). However, some of the blocks could be of a different size (Fig.2a) so some nodes might miss from the grid (Fig.2b).
Because of such irregularities we should expect that some nodes might connect "diagonally" or even have curved shapes (Fig.3a). This could make the length of a route to be a factor in the optimization process.
Also we should consider the cases of crescent streets, which will generate two alternate routes between the same two nodes, and the loops where the same node is linked with itself, mathematically called a multigraph (Fig.3b).
Also we need to mention that this graph is finite, planar, undirected and connected.
The shapefiles contain data expressed as vectors: points, lines and polygons.
(reference Euler's problem: Seven Bridges of Königsberg)

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShapeImport", "ShapeImport\ShapeImport.vcxproj", "{474DEC9C-6D02-4913-A916-F5597971052E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{474DEC9C-6D02-4913-A916-F5597971052E}.Debug|Win32.ActiveCfg = Debug|Win32
{474DEC9C-6D02-4913-A916-F5597971052E}.Debug|Win32.Build.0 = Debug|Win32
{474DEC9C-6D02-4913-A916-F5597971052E}.Release|Win32.ActiveCfg = Release|Win32
{474DEC9C-6D02-4913-A916-F5597971052E}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
This diff is collapsed.
#pragma once
#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iterator>
#include <bitset>
#include <intrin.h>
#include <stdint.h>
#include <math.h>
#include <iomanip>
#include <SFML\Graphics.hpp>
#include "ShapefileClass.h"
#include "IndexFileClass.h"
// /Byte Swap Reference - Convert Endians
/*
http://stackoverflow.com/questions/105252/how-do-i-convert-between-big-endian-and-little-endian-values-in-c
If you're using Visual C++ include intrin.h and call the following functions:
For 16 bit numbers: unsigned short _byteswap_ushort(unsigned short value);
For 32 bit numbers: unsigned long _byteswap_ulong(unsigned long value);
For 64 bit numbers: unsigned __int64 _byteswap_uint64(unsigned __int64 value);
The 8 bit numbers (chars) don't need to be converted.
For floats and doubles it's more difficult as with plain integers as these may or not may be in the
host machines byte-order. You can get little-endian floats on big-endian machines and vice versa.
Other compilers have similar intrinsics as well.
*/
#define BUF_SIZE 32768 // maximum buffer size
#define NAME_SIZE 128 // name size
#define BUF_SEP '*' // separator
#define CR 0x0D // carriage-return
#define LF 0x0A // line-feed
extern std::string fileBase; //File name without extension (all related shapefiles have same non-extension name)
extern std::string fileLocation; //File location - everything up to and including the folder it is in
extern char* _fileName;
extern std::string nodeGraph;
extern std::vector<FILE*> filesList;
extern std::vector<FILE*> indexList;
extern std::vector<std::string> fileNameList;
#define SCALE 100
#define EPSILON 0.00000000001
#define COMPRESS 1
// Default filtering box
#define MINX 70000
#define MINY 5400000
#define MAXX 90000
#define MAXY 5600000
extern long recValid;
extern long recDiscard;
struct PathingNode
{
unsigned int nodeID; //ID corresponding with ID of MainNode nodes
double fCost;
double gCost;
double hCost;
double x;
double y;
PathingNode* parent;
std::vector<PathingNode*> adjacentsList;
};
struct MainNode
{
unsigned int nodeID;
unsigned int header;
double x;
double y;
std::vector<MainNode*> adjacentsList;
};
// array[0] contains Record #1
extern std::vector<Point> pointList;
extern std::vector<PolyLine> polyLineList;
extern std::vector<Polygon> polyDataList;
extern std::vector<ShapefileHeader> headerList;
extern std::vector<sf::Color> colorList;
extern std::vector<sf::Texture> textureList;
extern std::vector<MainNode*> nodesList;
extern std::vector<sf::Sprite> drawPointsList;
const std::string fileExtMain = ".shp";
const std::string fileExtIndex = ".shx";
const std::string fileExtDBase = ".dbf";
extern sf::RenderWindow mainWindow;
extern sf::View mainView;
/* Enum for displayDebug
0 - Display no text
1 - Display 'regular' text
2 - Display header log
4 - Display header & record header logs
8 - Display record header contents
16 - Display all contents
~
31 - Display ALL logs
*/
enum _showDebug
{
SHOW_TEXT = 1, // 0000001
SHOW_HEADER = 2, // 0000010
SHOW_RECORD = 4, // 0000100
SHOW_CONTENT = 8, // 0001000
SHOW_POINTS = 16, // 0010000
SHOW_SEARCH = 32, // 0100000
SHOW_MOUSE = 64, // 1000000
SHOW_MAX
};
const int displayDebug = SHOW_TEXT + SHOW_HEADER + SHOW_MOUSE;
struct LineSegment
{
unsigned int header;
unsigned int record;
unsigned int part;
sf::VertexArray vertexList;
std::vector<sf::Sprite> spriteList;
};
extern std::vector<LineSegment> routesList;
extern sf::VertexArray pathLinesList;
extern bool exportNodes;
extern bool doDrawing;
extern bool doCompress;
extern bool doSaveToFile;
extern bool showNodes;
extern void aStarPathFind(MainNode* _start, MainNode* _target);
extern double getDistance(PathingNode* _init, PathingNode* _comp);
extern double getDistance(PathingNode* _init, MainNode* _comp);
extern double getDistance(sf::Sprite _init, MainNode* _comp);
extern double getDistance(sf::Vector2f _init, MainNode* _comp);
extern std::vector<PathingNode*> getNeighbours(MainNode* _current);
extern std::vector<MainNode*> retracePathPointer(PathingNode* _start, PathingNode* _end);
extern void loadNodeGraph(std::string _nodeGraph);
extern void exportNodeGraph(std::vector<MainNode*> _list);
extern void relinkNodes(std::vector<MainNode*> _nodesList);
#pragma once
/*
The offset of a record in the main file is the number of 16-bit words from
the start of the main file to the first byte of the record header for the record.
Thus, the offset for the first record in the main file is 50, given the 100-byte header.
The content length stored in the index record is the same as the value stored in the main
file record header.
*/
class Record
{
int offset; //Big Endian
int contentLength; //Big Endian
};
#pragma once
// https://www.esri.com/library/whitepapers/pdfs/shapefile.pdf
/*
Value Shape Type
--------------------------
0 Null Shape
1 Point
3 PolyLine
5 Polygon
8 MultiPoint
11 PointZ
13 PolyLineZ
15 PolygonZ
18 MultiPointZ
21 PointM
23 PolyLineM
25 PolygonM
28 MultiPointM
31 MultiPatch
File Length: The value for file length is the total length of the file in 16-bit words
(including the fifty 16-bit words that make up the header).
All the non-Null shapes in a shapefile are required to be of the same shape type.
*/
#define FILE_HEADER_LEN 100
class ShapefileHeader
{
public:
int fileCode;
int B04;
int B08;
int B12;
int B16;
int B20;
int fileLength; //Big Endian ^
int version; //Little Endian v
int shapeType;
long double minX;
long double minY;
long double maxX;
long double maxY;
long double minZ;
long double maxZ;
long double minM;
long double maxM;
};
/*
Endianness:
With big-endian the most-significant byte of a word is stored
at a particular memory address and the subsequent bytes are stored
in the following higher memory addresses, the least significant byte
thus being stored at the highest memory address.
Little-endian format reverses the order and stores the least-significant byte
at the lower memory address with the most significant byte being stored
at the highest memory address.
*/
class RecordHeader //Big Endian
{
public:
int recordNumber; //Begins at 1, NOT ZERO
int contentLength;
};
class Point //ShapeType = 0
{
public:
int shape;
long double x;
long double y;
int header;
bool valid;
};
/*
The content length for a record is the length of the record contents section measured in
16-bit words. Each record, therefore, contributes (4 + content length) 16-bit words
toward the total length of the file, as stored at Byte 24 in the file header.
*/
class MultiPoint
{
public:
double box[4]; //Bounding Box is stored in the order Xmin, Ymin, Xmax, Ymax
int numPoints;
std::vector<Point> points; // [numPoints]
};
struct vpart
{
int index;
bool valid;
};
class PolyLine
{
public:
long double box[4]; // Bounding Box for the PolyLine stored in the order Xmin, Ymin, Xmax, Ymax.
int numParts; // The number of parts in the PolyLine.
int numPoints; // The total number of points for all parts.
std::vector<vpart> parts; // An array of length NumParts. Stores, for each PolyLine, the index of its first point in the points array. Array indexes are with respect to 0.
std::vector<Point> points; // An array of length NumPoints. The points for each part in the PolyLine are stored end to end. The points for Part 2 follow the points for Part 1, and so on. The parts array holds the array index of the starting point for each part. There is no delimiter in the points array between parts.
int shape;
int header;
bool valid;
};
class Polygon
{
public:
long double box[4]; // The Bounding Box for the polygon stored in the order Xmin, Ymin, Xmax, Ymax.
int numParts; // The number of rings in the polygon.
int numPoints; // The total number of points for all rings.
std::vector<vpart> parts; // An array of length NumParts. Stores, for each ring, the index of its first point in the points array. Array indexes are with respect to 0.
std::vector<Point> points; // An array of length NumPoints. The points for each ring in the polygon are stored end to end. The points for Ring 2 follow the points for Ring 1, and so on. The parts array holds the array index of the starting point for each ring. There is no delimiter in the points array between rings.
int shape;
int header;
bool valid;
};
class PointM
{
public:
double x;
double y;
double m;
};
class MultiPointM
{
public:
double box[4]; // Bounding Box for the MultiPointM stored in the order Xmin, Ymin, Xmax, Ymax
int numPoints;
std::vector<PointM> points; // An array of Points of length NumPoints
double mRange[2]; // The minimum and maximum measures for the MultiPointM stored in the order Mmin, Mmax
std::vector<double> mArray; // An array of measures of length NumPoints
};
class PolyLineM
{
public:
double box[4]; // Bounding Box for the PolyLineM stored in the order Xmin, Ymin, Xmax, Ymax.
int numParts; // The number of parts in the PolyLineM
int numPoints; // The total number of points for all parts
std::vector<int> parts; // An array of length NumParts. Stores, for each part, the index of its first point in the points array. Array indexes are with respect to 0.
std::vector<PointM> points; // An array of length NumPoints. The points for each part in the PolyLineM are stored end to end. The points for Part 2 follow the points for Part 1, and so on. The parts array holds the array index of the starting point for each part.There is no delimiter in the points array between parts.
double mRange[2]; // The minimum and maximum measures for the MultiPointM stored in the order Mmin, Mmax
std::vector<double> mArray; // An array of length NumPoints. The measures for each part in the PolyLineM are stored end to end. The measures for Part 2 follow the measures for Part 1, and so on. The parts array holds the array index of the starting point for each part.There is no delimiter in the measure array between parts
};
class PolygonM
{
public:
double box[4]; // Bounding Box for the PolygonM stored in the order Xmin, Ymin, Xmax, Ymax.
int numParts; // The number of rings in the PolygonM
int numPoints; // The total number of points for all rings.
std::vector<int> parts; // An array of length NumParts. Stores, for each ring, the index of its first point in the points array. Array indexes are with respect to 0.
std::vector<PointM> points; // An array of length NumPoints. The points for each ring in the PolygonM are stored end to end. The points for Ring 2 follow the points for Ring 1, and so on.The parts array holds the array index of the starting point for each ring.There is no delimiter in the points array between rings.
double mRange[2]; // The minimum and maximum measures for the PolygonM stored in the order Mmin, Mmax.
std::vector<double> mArray; // An array of length NumPoints. The measures for each ring in the PolygonM are stored end to end. The measures for Ring 2 follow the measures for Ring 1, and so on.The parts array holds the array index of the starting measure for each ring.There is no delimiter in the measure array between rings.
};
class PointZ
{
public:
double x;
double y;
double m;
double z;
};
/*
The Bounding Box is stored in the order Xmin, Ymin, Xmax, Ymax.
The bounding Z Range is stored in the order Zmin, Zmax. Bounding M Range is stored
in the order Mmin, Mmax.
*/
class MultiPointZ
{
public:
double box[4];
int numPoints;
std::vector<PointZ> points;
double zRange[2];
std::vector<double> zArray;
double mRange[2];
std::vector<double> mArray;
};
class PolyLineZ
{
public:
double box[4];
int numPoints;
int numParts;
std::vector<int> parts;
std::vector<PointZ> points;
double zRange[2];
std::vector<double> zArray;
double mRange[2];
std::vector<double> mArray;
};
/*
The following are important notes about PolygonZ shapes:
The rings are closed (the first and last vertex of a ring MUST be the same).
The order of rings in the points array is not significant.
*/
class PolygonZ
{
public:
double box[4];
int numParts;
int numPoints;
std::vector<int> parts;
std::vector<PointZ> points;
double zRange[2];
std::vector<double> zArray;
double mRange[2];
std::vector<double> mArray;
};
/*
Value Part Type
0 Triangle Strip
1 Triangle Fan
2 Outer Ring
3 Inner Ring
4 First Ring
5 Ring
*/
/*
The following are important notes about MultiPatch shapes:
If a part is a ring, it must be closed (the first and last vertex of a ring MUST be the
same).
The order of parts that are rings in the points array is significant: Inner Rings must
follow their Outer Ring; a sequence of Rings representing a single surface patch must
start with a ring of the type First Ring.
Parts can share common boundaries, but parts must not intersect and penetrate each
other.
*/
class MultiPatch
{
public:
double box[4];
int numParts;
int numPoints;
std::vector<int> parts;
std::vector<int> partTypes;
std::vector<PointZ> points;
double zRange[2];
std::vector<double> zArray;
double mRange[2];
std::vector<double> mArray;
};
/* Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _IEEE754_H
#define _IEEE754_H 1
#include <features.h>
#include <endian.h>
__BEGIN_DECLS
union ieee754_float
{
float f;
/* This is the IEEE 754 single-precision format. */
struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:8;
unsigned int mantissa:23;
#endif /* Big endian. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int negative:1;
#endif /* Little endian. */
} ieee;
/* This format makes it easier to see if a NaN is a signalling NaN. */
struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:8;
unsigned int quiet_nan:1;
unsigned int mantissa:22;
#endif /* Big endian. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int mantissa:22;
unsigned int quiet_nan:1;
unsigned int exponent:8;
unsigned int negative:1;
#endif /* Little endian. */
} ieee_nan;
};
#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */
union ieee754_double
{
double d;
/* This is the IEEE 754 double-precision format. */
struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:11;
/* Together these comprise the mantissa. */
unsigned int mantissa0:20;
unsigned int mantissa1:32;
#endif /* Big endian. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
# if __FLOAT_WORD_ORDER == BIG_ENDIAN
unsigned int mantissa0:20;
unsigned int exponent:11;
unsigned int negative:1;
unsigned int mantissa1:32;
# else
/* Together these comprise the mantissa. */
unsigned int mantissa1:32;
unsigned int mantissa0:20;
unsigned int exponent:11;
unsigned int negative:1;
# endif
#endif /* Little endian. */
} ieee;
/* This format makes it easier to see if a NaN is a signalling NaN. */
struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:11;
unsigned int quiet_nan:1;
/* Together these comprise the mantissa. */
unsigned int mantissa0:19;
unsigned int mantissa1:32;
#else
# if __FLOAT_WORD_ORDER == BIG_ENDIAN
unsigned int mantissa0:19;
unsigned int quiet_nan:1;
unsigned int exponent:11;
unsigned int negative:1;
unsigned int mantissa1:32;
# else
/* Together these comprise the mantissa. */
unsigned int mantissa1:32;
unsigned int mantissa0:19;
unsigned int quiet_nan:1;
unsigned int exponent:11;
unsigned int negative:1;
# endif
#endif
} ieee_nan;
};
#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */
union ieee854_long_double
{
long double d;
/* This is the IEEE 854 double-extended-precision format. */
struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:15;
unsigned int empty:16;
unsigned int mantissa0:32;
unsigned int mantissa1:32;
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
# if __FLOAT_WORD_ORDER == BIG_ENDIAN
unsigned int exponent:15;
unsigned int negative:1;
unsigned int empty:16;
unsigned int mantissa0:32;
unsigned int mantissa1:32;