Skip to main content
留学咨询

辅导案例-ECE297

By May 15, 2020No Comments

ECE297 Communication and Design Winter 2020 ECE297 Quick Start Guide OSM “A map is the greatest of all epic poems. Its lines and colors show the realization of great dreams.” –Gilbert H. Grosvenor 1 Overview OpenStreetMap (OSM) is an open-source project that creates free, editable geographic data for the world. This data can be downloaded for free as one huge file (1 TB when uncompressed) that represents the entire planet. Fortunately, it is also possible to select smaller regions to download. For more info, see this. You can view the newest OSM map on your web browser at https://www. openstreetmap.org/. 2 Data Representation The basic components of the OSM data are nodes, ways and relations. • A node is a (latitude, longitude) point. • A way is an ordered list of nodes that makes up a contour such as a portion of a road (StreetSegment) or a park boundary (Feature). • A relation is a group of nodes, ways or other relations that form some more complex logical concept. For example a subway line would be a relation that groups the nodes that represent the subway stations, and the ways that represent the subway tracks. Each data element (node, way and relation) can have tags that describe the attached element. Moreover, each data element in a relation can optionally have a role within the relation. For more detail on OSM’s data representation, see https://wiki. openstreetmap.org/wiki/Elements. 3 OSM Layer 1 API The milestone 1 assignment document explains how to use the “layer 2” StreetsDatabaseAPI, and we assume you have read that document already. The layer 2 (StreetsDatabase) API provides OpenStreetMap (OSM) data in a simpler and more organized format than the “layer 1” OSM- DatabaseAPI described below, but the “layer 1” API provides access to additional OSM data. This Page 1 of 11 ECE297 Communication and Design Winter 2020 data is generally less structured so it will require more investigation to determine what data you want and how to use it. Listing 1 lists the functions available in this API. 1 /* 2 * Copyright 2020 University of Toronto 3 * 4 * Permission is hereby granted, to use this software and associated 5 * documentation files (the “Software”) in course work at the University 6 * of Toronto, or for personal use. Other uses are prohibited, in 7 * particular the distribution of the Software either publicly or to third 8 * parties. 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 * SOFTWARE. 20 */ 21 #ifndef OSMDATABASEAPI_H 22 #define OSMDATABASEAPI_H 23 #include 24 #include “OSMID.h” 25 #include “LatLon.h” 26 27 #include “OSMEntity.h” 28 #include “OSMNode.h” 29 #include “OSMWay.h” 30 #include “OSMRelation.h” 31 32 33 /******************************************************************************* 34 * LAYER-1 API INTRODUCTION 35 * 36 * ** This is a more complex API than layer 2 which is built on top of it; 37 * please start with layer 2. The information accessible here 38 * is not _required_ for any milestone, though it may help you provide 39 * additional features. ** 40 * 41 * The Layer-1 API handles parsing the OSM XML data, and removes some features 42 * which are not of interest (eg. timestamps, the user names who made changes) 43 * to conserve time and space. It also loads/saves a binary format that is 44 * pre-parsed and so more compact and faster to load. 45 * 46 * 47 * The object model of this library and API follows the OSM model closely. It 48 * is a lean, flexible model with only three distinct entity types, each of 49 * which carries all of its non-spatial data as attributes. 50 * 51 * There are three types of OSM Entities: Page 2 of 11 ECE297 Communication and Design Winter 2020 52 * Node A point with lat/lon coordinates and zero 53 * Way A collection of nodes, either a path (eg. street, bike path) or 54 * closed polygon (eg. pond, building) 55 * Relation A collection of nodes, ways, and/or relations that share some 56 * common meaning (eg. large lakes/rivers) 57 * 58 * Each entity may have associated zero or more attributes of the form key=value, 59 * eg. name=”CN Tower” or type=”tourist trap”. 60 * 61 * After processing by osm2bin, files are stored in {mapname}.osm.bin ready to 62 * use in this API. 63 */ 64 65 // Load the (lower-level) layer-1 OSM database; call this before calling any other 66 // layer-1 API function. Returns true if successful, false otherwise. 67 // These files are named {cityname}.osm.bin 68 bool loadOSMDatabaseBIN(const std::string&); 69 70 // Close the layer-1 OSM database and release memory. You must close one map 71 // before loading another. 72 void closeOSMDatabase(); 73 74 75 /******************************************************************************* 76 * Entity access 77 * 78 * Provides functions to iterate over all nodes, ways, relations in the database. 79 * 80 * NOTE: The indices here have no relation at all to the indices used in the 81 * layer-2 API, or to the OSM IDs. 82 * 83 * Once you have the OSMNode/OSMWay/OSMRelation pointer, you can use it to 84 * access methods of those types or the tag interface described below. 85 * The most basic method supported by OSMNode, OSMWay, and OSMRelation is 86 * OSMID(), which returns the OSMID (a basic class containing a 64-bit integer). 87 * The OSMID for any OSMNode/OSMWay/OSMRelation is globally unique (never 88 * re-used for any other OSMNode etc. anywehere in the world). 89 * For example: 90 * OSMNode *e = getNodeByIndex(0); // Gets the first OSM Node in this city 91 * OSMID id = e->id(); // A 64-bit int (big); unique id 92 */ 93 94 int getNumberOfNodes(); 95 int getNumberOfWays(); 96 int getNumberOfRelations(); 97 98 const OSMNode* getNodeByIndex (int idx); 99 const OSMWay* getWayByIndex (int idx); 100 const OSMRelation* getRelationByIndex (int idx); 101 102 103 /******************************************************************************* 104 * Entity tag access 105 * Page 3 of 11 ECE297 Communication and Design Winter 2020 106 * OSMNode, OSMWay, and OSMRelation are all objects derived from OSMEntity, 107 * which carries attribute tags. The functions below allow you to iterate 108 * through the tags on a given entity acquired above, for example: 109 * 110 * for(int i=0;i111 * { 112 * std::string key,value; 113 * std::tie(key,value) = getTagPair(e,i); 114 * // … do useful stuff … 115 * } 116 */ 117 118 int getTagCount(const OSMEntity* e); 119 std::pair getTagPair(const OSMEntity* e, int idx); 120 121 /******************************************************************************* 122 * OSMNode Functions (OSMNode is a point with lat/lon coordinates) 123 * 124 * The getNodeCoords() function returns the coordinates of the OSMNode 125 */ 126 LatLon getNodeCoords(const OSMNode* n); 127 128 /******************************************************************************* 129 * OSMWay Functions (OSMWay is a collection of nodes) 130 * 131 * The getWayMembers() function returns the OSMIDs of the nodes that form the way 132 * 133 * The isClosedWay() function returns false if the OSMWay is open (a path) and 134 * returns true if the OSMWay is closed (closed polygon) 135 */ 136 const std::vector& getWayMembers(const OSMWay* w); 137 bool isClosedWay(const OSMWay* w); 138 139 /******************************************************************************* 140 * OSMRelation Functions (OSMRelation is a collection of nodes, ways, and/or relations) 141 * 142 * The getRelationMembers() function returns the TypedOSMIDs of the nodes/ways/ 143 * relations that form the relation. 144 * TypedOSMID can do everyting an OSMID
can (i.e. it inherits from OSMID), but 145 * it also has a type, which is either Node, Way or Relation. 146 * For example: 147 * (tid.type() == TypedOSMID::Way) returns true if tid is an OSMID of a way 148 * 149 * The getRelationMemberRoles() function returns the role of each member of the 150 * relation. 151 * A role is a string that may exist (it is optional in OSM) that describes the 152 * role of a member within the relation. 153 * For example, a member (a way) of a relation that represents a subway line can 154 * have a “platform” role to represent a platform in that line. 155 */ 156 std::vector getRelationMembers(const OSMRelation* r); 157 std::vector getRelationMemberRoles(const OSMRelation* r); 158 159 #endif Page 4 of 11 ECE297 Communication and Design Winter 2020 Listing 1: Layer 1 libstreetsdatabase API, from OSMDatabaseAPI.h. To use this API, #include OSMDatabaseAPI.h in your code, and call loadOSMDatabaseBin(mapname) where mapname could be (for example) /cad2/ece297s/public/maps/toronto_canada.osm.bin. You can then make calls (e.g. getNumberOfNodes()) to get the number of OSM nodes, ways and relations in this map. Nodes, ways and relations are collectively called OSM entities. Each OSMEntity has a unique ID (OSM ID) which you can get by calling id(). In addition, OSM entities can each have tags that are (key, value) pairs of strings that store additional information; for example a key of “name” would have a value of “High Park” for the OSM way that gives the boundary of High Park in Toronto. You can determine the location of an OSMNode by calling getNodeCoords(OSMNode*) which will return the LatLon of that node. To obtain other information about an OSMNode, you query getNodeByIndex (index), where index can be any value from 0 to getNumberOfNodes() – 1. This function returns a pointer to an OSMNode object, which inherits from OSMEntity. Using this pointer, you can query other functions (getTagCount(OSMEntity*) and getTagPair(OSMEntity*, index) to obtain the tags – (key, value) pairs – that are relevant to this OSM object. You obtain extra information (tags) about ways and relations in a very similar way. For more details on the values of different attributes, go to http://wiki.openstreetmap.org/wiki/Map_Features. You can get the nodes that form an OSMWay by calling getWayMembers(OSMWay*). This function returns a list of the OSM IDs that identify these nodes. Similarly, you can get the nodes, ways and/or relations that form an OSMRelation by calling getRelationMembers(OSMRelation*). This function returns a list of the typed OSM IDs that identify the relation members. A typed OSM ID is the same as the OSM ID but it has a type that identifies whether it is the OSM ID of a node, a way or a relation. Page 1 of 1 7/8/2014file:///C:/Users/Mohamed/Desktop/light-bulb-7.svg To determine the data you are looking for, such as what tags might be relevant, you can search the relevant map.xml file in /cad2/ece297s/public/maps/. These files are large, so either use a text editor that can handle very large files or Unix commands like less or grep. Finally, there are API calls in StreetsDatabaseAPI.h (i.e. the layer 2 API) that return the OSM ID and entity type for intersections, points of interest, street segments and features. This data can be used to look up the OSM tag information associated with each element using the layer 1 API calls described above. 4 Walkthrough with an Example This section will walk you through an example on how to extract information from the OSM data. We are going to extract information about the subways in a city. The code provided in this section is not optimized; it is slow. If you want to extract information from the OSM data, you will have to think of a better way to write the code by building the appropriate data structures. Page 5 of 11 ECE297 Communication and Design Winter 2020 Subway stations are represented in OSM data by OSM nodes (recall that an OSM node is a point on the earth’s surface defined by its latitude and longitude). They have a tag of “station”=“subway” (where station is the key and subway is the value). Hence by looping through all OSM nodes and checking which have this tag, we can find all the subway stations in a city. The code listed in Listing 2 gets the nodes that represents Toronto’s subway stations. It also prints the names of these stations by getting the name tag of the OSM nodes. This code can be found in the zip file accompanying this guide, named osm_ex1.cpp. The output of this code is shown in Listing 3. 1 /* OSM Layer Example 1 */ 2 3 #include 4 #include 5 #include “OSMDatabaseAPI.h” 6 using namespace std; 7 8 int main(int, char**) { 9 10 // Toronto OSM map 11 string map_name = “/cad2/ece297s/public/maps/toronto_canada.osm.bin”; 12 13 // Load layer 1 OSM database 14 loadOSMDatabaseBIN(map_name); 15 16 vector osm_subway_stations; 17 18 // Loop through all OSM nodes 19 for (unsigned i = 0; i < getNumberOfNodes(); i++) { 20 const OSMNode *currNode = getNodeByIndex(i); 21 22 // Check the tag of the currNode 23 for (unsigned j = 0; j < getTagCount(currNode); j++) { 24 pair tagPair = getTagPair(currNode, j); 25 26 // Push nodes with the station=subway tag 27 if (tagPair.first == "station" && tagPair.second == "subway") { 28 osm_subway_stations.push_back(currNode); 29 break; 30 } 31 } 32 } 33 34 // Print subway station names 35 cout << "Subway Stations:" << endl; 36 for (unsigned i = 0; i < osm_subway_stations.size(); i++) { 37 38 // Get the name tag 39 for (unsigned j = 0; j < getTagCount(osm_subway_stations[i]); j++) { 40 pair tagPair = getTagPair(osm_subway_stations[i], j); 41 42 if (tagPair.first == "name") { 43 cout << "\t" << tagPair.second << endl; 44 break; 45 } Page 6 of 11 ECE297 Communication and Design Winter 2020 46 } 47 } 48 49 // Close layer 1 OSM database 50 closeOSMDatabase(); 51 52 return 0; 53 } Listing 2: Example 1 1 Subway Stations: 2 Bay 3 Dundas West 4 St. Patrick 5 Dundas 6 St. George 7 Osgoode 8 St. Andrew 9 King 10 Queen 11 College 12 Wellesley 13 St. Clair 14 Eglinton 15 Lawrence 16 York Mills 17 Finch 18 Old Mill 19 North York Centre 20 Summerhill 21 Queen’s Park 22 Sheppard West 23 Keele 24 High Park 25 Kipling 26 Glencairn 27 Bloor-Yonge 28 Runnymede 29 Jane 30 Sherbourne 31 Castle Frank 32 Vaughan Metropolitan Centre 33 Kennedy 34 Downsview Park 35 Finch West 36 Christie 37 Sheppard-Yonge 38 Bayview 39 Bessarion 40 Don Mills 41 Leslie 42 Davisville 43 Rosedale Page 7 of 11 ECE297 Communication and Design Winter 2020 44 Union 45 Spadina 46 Museum 47 St. Clair West 48 Dupont 49 Eglinton West 50 Wilson 51 Yorkdale 52 Lawrence West 53 Highway 407 54 Pioneer Village 55 Chester 56 Broadview 57 Pape 58 Royal York 59 Islington 60 Lansdowne 61 Dufferin 62 Ossington 63 Bathurst 64 Warden 65 Victoria Park 66 Main Street 67 Woodbine 68 Coxwell 69 Greenwood 70 Donlands 71 York University Listing 3: Example 1 Output The aforementioned method does not provide information about subway lines; it does not provide information about how the subway stations are connected together, or to which subway line they belong. OSM relations which can group nodes, ways and/or relations together provide such information. A subway line is represented by an OSM relation that groups the nodes that represent the subway stations, and the ways that represent the subway tracks. It has a tag of “route”=“subway”. The code listed in Listing 4 gets the subway lines of Toronto, and prints the name, color, and subway stations of each line. First, we loop through all OSM relations and check which have the “route”=“subway” tag to find all the subway lines in the city. For each relation (subway line), we get its name and color by looking for “name" and “colour" tags. Then we use getRelationMembers() to get the OSM IDs of the members of each relation. A member of type Node represents a subway station, while a member of type Way represents a subway track. This code can be found in the zip file accompanying this guide, named osm_ex2.cpp. The output of this code is shown in Listing 5. 1 /* OSM Layer Example 2 */ 2 3 #include 4 #include 5 #include "OSMDa tabaseAPI.h" 6 using namespace std; 7 Page 8 of 11 ECE297 Communication and Design Winter 2020 8 int main(int, char**) { 9 10 // Toronto OSM map 11 string map_name = "/cad2/ece297s/public/maps/toronto_canada.osm.bin"; 12 13 // Load layer 1 OSM database 14 loadOSMDatabaseBIN(map_name); 15 16 vector osm_subway_lines; 17 18 // Loop through all OSM relations 19 for (unsigned i = 0; i < getNumberOfRelations(); i++) { 20 const OSMRelation *currRel = getRelationByIndex(i); 21 22 // Check the tag of the currRel 23 for (unsigned j = 0; j < getTagCount(currRel); j++) { 24 pair tagPair = getTagPair(currRel, j); 25 26 // Push relations with the route=subway tag 27 if (tagPair.first == "route" && tagPair.second == "subway") { 28 osm_subway_lines.push_back(currRel); 29 break; 30 } 31 } 32 } 33 34 // For each subway line (relation), get its name, color, and members 35 for (unsigned i = 0; i < osm_subway_lines.size(); i++) { 36 37 // Get subway line color and name 38 for (unsigned j = 0; j < getTagCount(osm_subway_lines[i]); j++) { 39 pair tagPair = getTagPair(osm_subway_lines[i], j); 40 41 if (tagPair.first == "colour") { 42 cout << "Subway line color: " << tagPair.second << endl; 43 } else if (tagPair.first == "name") { 44 cout << "Subway line name: " << tagPair.second << endl; 45 } 46 } 47 48 // Get relation members 49 vector route_members = getRelationMembers(osm_subway_lines[i]); 50 51 // Print subway station names 52 cout << "Subway line stations:" << endl; 53 for(unsigned j = 0; j < route_members.size(); j++) { 54 55 // A member of type node represents a subway station 56 if(route_members[j].type() == TypedOSMID::Node) { 57 58 const OSMNode *currNode = nullptr; 59 60 // Node lookup by OSMID 61 for (unsigned k = 0; k < getNumberOfNodes(); k++) { Page 9 of 11 ECE297 Communication and Design Winter 2020 62 currNode = getNodeByIndex(k); 63 if (currNode->id() == route_members[j]) 64 break; 65 } 66 67 // Get the name tag of that node 68 for (unsigned k = 0; k < getTagCount(currNode); k++) { 69 pair tagPair = getTagPair(currNode, k); 70 71 if (tagPair.first == "name") { 72 cout << "\t" << tagPair.second << endl; 73 break; 74 } 75 } 76 77 } 78 } 79 } 80 81 // Close layer 1 OSM database 82 closeOSMDatabase(); 83 84 return 0; 85 } Listing 4: Example 2 1 Subway line name: Line 2 Bloor-Danforth (Kipling -> Kennedy) 2 Subway line color: green 3 Subway line stations: 4 Kipling 5 Islington 6 Royal York 7 Old Mill 8 Jane 9 Runnymede 10 High Park 11 Keele 12 Dundas West 13 Lansdowne 14 Dufferin 15 Ossington 16 Christie 17 Bathurst 18 Spadina 19 St. George 20 Bay 21 Bloor-Yonge 22 Sherbourne 23 Castle Frank 24 Broadview 25 Chester 26 Pape 27 Donlands Page 10 of 11 ECE297 Communication and Design Winter 2020 28 Greenwood 29 Coxwell 30 Woodbine 31 Main Street 32 Victoria Park 33 Warden 34 Kennedy 35 Subway line name: Line 1 Yonge-University (Vaughan Metropolitan Centre -> Finch) 36 Subway line color: yellow 37 Subway line stations: 38 Vaughan Metropolitan Centre 39 Highway 407 40 Pioneer Village 41 York University 42 Finch West 43 Downsview Park 44 Sheppard West 45 Wilson 46 Yorkdale 47 Lawrence West 48 Glencairn 49 Eglinton West 50 St. Clair West 51 Dupont 52 Spadina 53 St. George 54 Museum 55 Queen’s Park 56 St. Patrick 57 Osgoode 58 St. Andrew 59 Union 60 King 61 Queen 62 Dundas 63 College 64 Wellesley 65 Bloor-Yonge 66 Rosedale 67 Summerhill 68 St. Clair 69 Davisville 70 Eglinton 71 Lawrence 72 York Mills 73 Sheppard-Yonge 74 North York Centre 75 Finch 76 … Listing 5: Example 2 Output Page 11 of 11

admin

Author admin

More posts by admin