Skip to content

Commit a9846f6

Browse files
committed
Merge pull request #127 from AmericanRedCross/deployments-ui1
Deployments PR1
2 parents 513415c + bf71c31 commit a9846f6

62 files changed

Lines changed: 1714 additions & 77 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

MapboxAndroidSDK/build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ dependencies {
2828
compile 'com.squareup.okhttp:okhttp-urlconnection:2.4.0'
2929
compile 'com.nineoldandroids:library:2.4.0'
3030
compile 'com.jakewharton:disklrucache:2.0.2'
31+
compile 'commons-codec:commons-codec:1.10'
3132
}
3233

3334
android {
@@ -45,6 +46,12 @@ android {
4546
}
4647
}
4748

49+
packagingOptions {
50+
exclude 'LICENSE.txt'
51+
exclude 'META-INF/LICENSE.txt'
52+
exclude 'META-INF/NOTICE.txt'
53+
}
54+
4855
compileOptions {
4956
sourceCompatibility JavaVersion.VERSION_1_7
5057
targetCompatibility JavaVersion.VERSION_1_7
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package com.spatialdev.osm.model;
2+
3+
4+
import android.test.InstrumentationTestCase;
5+
6+
import org.apache.commons.codec.binary.Hex;
7+
import org.apache.commons.codec.digest.DigestUtils;
8+
9+
import java.io.InputStream;
10+
import java.util.List;
11+
12+
public class ChecksumTest extends InstrumentationTestCase {
13+
14+
private OSMWay way;
15+
private OSMWay way2;
16+
private OSMNode donutHappy;
17+
18+
public void setUp() throws Exception {
19+
super.setUp();
20+
InputStream in = getInstrumentation().getTargetContext().getResources().getAssets().open("test/osm/checksum_way.osm");
21+
OSMDataSet ds = OSMXmlParser.parseFromInputStream(in);
22+
way = ds.getClosedWays().get(0);
23+
24+
InputStream in2 = getInstrumentation().getTargetContext().getResources().getAssets().open("test/osm/checksum_way2.osm");
25+
OSMDataSet ds2 = OSMXmlParser.parseFromInputStream(in2);
26+
way2 = ds2.getClosedWays().get(0);
27+
28+
InputStream in3 = getInstrumentation().getTargetContext().getResources().getAssets().open("test/osm/donut_happy.osm");
29+
OSMDataSet ds3 = OSMXmlParser.parseFromInputStream(in3);
30+
donutHappy = ds3.getStandaloneNodes().get(0);
31+
}
32+
33+
public void tearDown() throws Exception {
34+
super.tearDown();
35+
}
36+
37+
public void testSha1OnAString() throws Exception {
38+
String testStr = "test";
39+
String sha1 = new String(Hex.encodeHex(DigestUtils.sha1(testStr)));
40+
assertEquals("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", sha1);
41+
}
42+
43+
public void testWayTagsAsSortedKVString() throws Exception {
44+
String str = way.tagsAsSortedKVString().toString();
45+
assertEquals("buildingcommercialbuilding:conditiongoodbuilding:levels1building:materialconcretenameJava the Hut", str);
46+
}
47+
48+
public void testWayChecksum() throws Exception {
49+
String checksum = way.checksum();
50+
assertEquals("add90109a0ca34d12d28292ccd05c588d2220f0a", checksum);
51+
}
52+
53+
public void testWayChecksum2() throws Exception {
54+
String checksum = way2.checksum();
55+
assertEquals("3854296ef0b8fc4810454dd5d8de79dc59f7f007", checksum);
56+
}
57+
58+
public void testNodesInWayChecksums() throws Exception {
59+
List<OSMNode> nodes = way.getNodes();
60+
for (OSMNode n : nodes) {
61+
long id = n.getId();
62+
if (id == 3969314187L) {
63+
assertEquals("6f3b2e85e05dbdc496f9250931693f7a3e427807", n.checksum());
64+
} else if (id == 3969314188L) {
65+
assertEquals("e52eb00f4e028a8010e32a9cfca788273f49a675", n.checksum());
66+
} else if (id == 3969314189L) {
67+
assertEquals("3f7514c1b2ca88dfc53fdd7daecc0851bfeba081", n.checksum());
68+
} else if (id == 3969314190L) {
69+
assertEquals("c3010e77a9f5d322bfd0081c607dfc7109b86ba9", n.checksum());
70+
}
71+
}
72+
}
73+
74+
public void testPreWayChecksum() throws Exception {
75+
String preChecksum = way.preChecksum();
76+
assertEquals("buildingcommercialbuilding:conditiongoodbuilding:levels1building:materialconcretenameJava the Hut6f3b2e85e05dbdc496f9250931693f7a3e427807c3010e77a9f5d322bfd0081c607dfc7109b86ba93f7514c1b2ca88dfc53fdd7daecc0851bfeba081e52eb00f4e028a8010e32a9cfca788273f49a6756f3b2e85e05dbdc496f9250931693f7a3e427807", preChecksum);
77+
}
78+
79+
public void testDonutHappyPreChecksum() throws Exception {
80+
String preChecksum = donutHappy.preChecksum();
81+
assertEquals("addr:citySacramentoaddr:housenumber5049-Daddr:postcode95841addr:stateCAaddr:streetCollege Oak Dr.amenitycafénameDonut Happyshopbakery38.65838277039187-121.3510830389408", preChecksum);
82+
}
83+
84+
public void testDonutHappyChecksum() throws Exception {
85+
String checksum = donutHappy.checksum();
86+
assertEquals("27b1bf1412ab7f02f0991e37d783f92d83ed1d52", checksum);
87+
}
88+
89+
public void testAccentEigu() throws Exception {
90+
String str = "café";
91+
String sha1 = new String(Hex.encodeHex(DigestUtils.sha1(str)));
92+
assertEquals("f424452a9673918c6f09b0cdd35b20be8e6ae7d7", sha1);
93+
}
94+
}

MapboxAndroidSDK/src/main/AndroidManifest.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="com.mapbox.mapboxsdk">
44
<application android:allowBackup="true"/>
5-
<uses-sdk android:minSdkVersion="9"/>
65
</manifest>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?xml version='1.0' encoding='UTF-8' ?><osm version="0.6" generator="OpenMapKit Android 0.18" user="test1"><node id="3969314187" version="1" changeset="36825360" timestamp="2016-01-26T20:59:44Z" user="test1" lat="38.6585651" lon="-121.350073" /><node id="3969314190" version="1" changeset="36825360" timestamp="2016-01-26T20:59:44Z" user="test1" lat="38.6583446" lon="-121.3501732" /><node id="3969314189" version="1" changeset="36825360" timestamp="2016-01-26T20:59:44Z" user="test1" lat="38.6583776" lon="-121.3502926" /><node id="3969314188" version="1" changeset="36825360" timestamp="2016-01-26T20:59:44Z" user="test1" lat="38.6585982" lon="-121.3501924" /><node id="3969314187" version="1" changeset="36825360" timestamp="2016-01-26T20:59:44Z" user="test1" lat="38.6585651" lon="-121.350073" /><way id="393886820" action="modify" version="1" changeset="36825360" timestamp="2016-01-30T20:04:36Z" user="test1"><nd ref="3969314187" /><nd ref="3969314190" /><nd ref="3969314189" /><nd ref="3969314188" /><nd ref="3969314187" /><tag k="building" v="commercial" /><tag k="building:material" v="concrete" /><tag k="building:condition" v="good" /><tag k="building:levels" v="1" /><tag k="name" v="Java the Hut" /></way></osm>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?xml version='1.0' encoding='UTF-8' ?><osm version="0.6" generator="OpenMapKit Android 0.18" user="test1"><node id="3969314244" version="1" changeset="36825360" timestamp="2016-01-26T20:59:45Z" user="test1" lat="38.6558196" lon="-121.3529546" /><node id="3969314245" version="1" changeset="36825360" timestamp="2016-01-26T20:59:45Z" user="test1" lat="38.6559387" lon="-121.3531296" /><node id="3969314246" version="1" changeset="36825360" timestamp="2016-01-26T20:59:45Z" user="test1" lat="38.6558719" lon="-121.3532042" /><node id="3969314247" version="1" changeset="36825360" timestamp="2016-01-26T20:59:45Z" user="test1" lat="38.6561341" lon="-121.3535895" /><node id="3969314248" version="1" changeset="36825360" timestamp="2016-01-26T20:59:45Z" user="test1" lat="38.656047" lon="-121.3536867" /><node id="3969314249" version="1" changeset="36825360" timestamp="2016-01-26T20:59:45Z" user="test1" lat="38.6556657" lon="-121.3531264" /><node id="3969314244" version="1" changeset="36825360" timestamp="2016-01-26T20:59:45Z" user="test1" lat="38.6558196" lon="-121.3529546" /><way id="393886827" action="modify" version="1" changeset="36825360" timestamp="2016-02-02T18:31:41Z" user="test1"><nd ref="3969314244" /><nd ref="3969314245" /><nd ref="3969314246" /><nd ref="3969314247" /><nd ref="3969314248" /><nd ref="3969314249" /><nd ref="3969314244" /><tag k="building" v="commercial" /><tag k="name" v="test" /></way></osm>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?xml version='1.0' encoding='UTF-8' ?><osm version="0.6" generator="OpenMapKit Android 0.18" user="test1"><node id="-12" action="modify" timestamp="2016-02-04T22:38:51Z" user="test1" lat="38.65838277039187" lon="-121.3510830389408"><tag k="name" v="Donut Happy" /><tag k="amenity" v="café" /><tag k="shop" v="bakery" /><tag k="addr:housenumber" v="5049-D" /><tag k="addr:street" v="College Oak Dr." /><tag k="addr:city" v="Sacramento" /><tag k="addr:state" v="CA" /><tag k="addr:postcode" v="95841" /></node></osm>

MapboxAndroidSDK/src/main/java/com/spatialdev/osm/model/OSMElement.java

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
package com.spatialdev.osm.model;
66

77
import java.io.IOException;
8+
import java.util.ArrayList;
89
import java.util.LinkedHashMap;
910
import java.util.LinkedList;
11+
import java.util.List;
1012
import java.util.Map;
1113
import java.util.Set;
1214

@@ -56,7 +58,7 @@ public abstract class OSMElement {
5658
/**
5759
* This can be used to keep track of which tag is currently selected in a tag editor
5860
* like OpenMapKit.
59-
* * *
61+
* * *
6062
*/
6163
protected String selectedTag;
6264

@@ -171,7 +173,36 @@ protected static long getUniqueNegativeId() {
171173
return negativeId--;
172174
}
173175

174-
void xml(XmlSerializer xmlSerializer) throws IOException {
176+
/**
177+
* All OSM Element types need to have this implemented. This checksum is composed
178+
* of the tags sorted alphabetically by key. The rest of the implementation is
179+
* defined differently whether it is Node, Way, or Relation.
180+
*
181+
* @return SHA-1 HEX checksum of the element
182+
*/
183+
public abstract String checksum();
184+
185+
/**
186+
* The tags are sorted by key, and each key, value is
187+
* iterated and concatenated to a String.
188+
*
189+
* @return
190+
*/
191+
public StringBuilder tagsAsSortedKVString() {
192+
List<String> keys = new ArrayList<>(tags.keySet());
193+
java.util.Collections.sort(keys);
194+
StringBuilder tagsStr = new StringBuilder();
195+
for (String k : keys) {
196+
String v = tags.get(k);
197+
if (v.length() > 0) {
198+
tagsStr.append(k);
199+
tagsStr.append(v);
200+
}
201+
}
202+
return tagsStr;
203+
}
204+
205+
void xml(XmlSerializer xmlSerializer, String omkOsmUser) throws IOException {
175206
// set the tags for the element (all element types can have tags)
176207
Set<String> tagKeys = tags.keySet();
177208
for (String tagKey : tagKeys) {
@@ -186,7 +217,7 @@ void xml(XmlSerializer xmlSerializer) throws IOException {
186217
}
187218
}
188219

189-
protected void setOsmElementXmlAttributes(XmlSerializer xmlSerializer) throws IOException {
220+
protected void setOsmElementXmlAttributes(XmlSerializer xmlSerializer, String omkOsmUser) throws IOException {
190221
xmlSerializer.attribute(null, "id", String.valueOf(id));
191222
if (isModified()) {
192223
xmlSerializer.attribute(null, "action", "modify");
@@ -207,11 +238,19 @@ protected void setOsmElementXmlAttributes(XmlSerializer xmlSerializer) throws IO
207238
} else if (timestamp != null) {
208239
xmlSerializer.attribute(null, "timestamp", timestamp);
209240
}
241+
/**
242+
* We want to put the OSM user set in OMK Android for all of the elements we are writing.
243+
* This is important, because when we are filtering in OMK iD, we need to be able to filter
244+
* by OSM user. The OSM user should refer to all elements affected by an edit. This means
245+
* that the OMK Android OSM user name should apply to nodes referenced by an edited way
246+
* as well (so that filtering gets the complete geometry in).
247+
*/
248+
xmlSerializer.attribute(null, "user", omkOsmUser);
210249
}
211250

212251
/**
213252
* Maintains state over which tag is selected in a tag editor UI
214-
* * *
253+
* * *
215254
* @param tagKey
216255
*/
217256
public void selectTag(String tagKey) {

MapboxAndroidSDK/src/main/java/com/spatialdev/osm/model/OSMNode.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import com.mapbox.mapboxsdk.overlay.Marker;
1111
import com.spatialdev.osm.marker.OSMMarker;
1212

13+
import org.apache.commons.codec.binary.Hex;
14+
import org.apache.commons.codec.digest.DigestUtils;
1315
import org.xmlpull.v1.XmlSerializer;
1416

1517
import java.io.IOException;
@@ -139,13 +141,32 @@ public Marker getMarker() {
139141
return marker;
140142
}
141143

144+
public String preChecksum() {
145+
StringBuilder str = tagsAsSortedKVString();
146+
str.append(lat);
147+
str.append(lng);
148+
return str.toString();
149+
}
150+
151+
/**
152+
* The checksum of an OSMNode is the sorted k,v of the tags
153+
* with the lat and long following.
154+
*
155+
* @return
156+
*/
157+
@Override
158+
public String checksum() {
159+
String str = preChecksum();
160+
return new String(Hex.encodeHex(DigestUtils.sha1(str)));
161+
}
162+
142163
@Override
143-
void xml(XmlSerializer xmlSerializer) throws IOException {
164+
void xml(XmlSerializer xmlSerializer, String omkOsmUser) throws IOException {
144165
xmlSerializer.startTag(null, "node");
145-
setOsmElementXmlAttributes(xmlSerializer);
166+
setOsmElementXmlAttributes(xmlSerializer, omkOsmUser);
146167
xmlSerializer.attribute(null, "lat", String.valueOf(lat));
147168
xmlSerializer.attribute(null, "lon", String.valueOf(lng));
148-
super.xml(xmlSerializer); // generates tags
169+
super.xml(xmlSerializer, omkOsmUser); // generates tags
149170
xmlSerializer.endTag(null, "node");
150171
}
151172

MapboxAndroidSDK/src/main/java/com/spatialdev/osm/model/OSMRelation.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
package com.spatialdev.osm.model;
66

7+
import org.apache.commons.codec.binary.Hex;
8+
import org.apache.commons.codec.digest.DigestUtils;
79
import org.xmlpull.v1.XmlSerializer;
810

911
import java.io.IOException;
@@ -49,16 +51,31 @@ public OSMRelation(String idStr,
4951
}
5052

5153
@Override
52-
void xml(XmlSerializer xmlSerializer) throws IOException {
54+
public String checksum() {
55+
StringBuilder str = tagsAsSortedKVString();
56+
for (OSMNode n : linkedNodes) {
57+
str.append(n.checksum());
58+
}
59+
for (OSMWay w : linkedWays) {
60+
str.append(w.checksum());
61+
}
62+
for (OSMRelation r : linkedRelations) {
63+
str.append(r.checksum());
64+
}
65+
return new String(Hex.encodeHex(DigestUtils.sha1(str.toString())));
66+
}
67+
68+
@Override
69+
void xml(XmlSerializer xmlSerializer, String omkOsmUser) throws IOException {
5370
xmlSerializer.startTag(null, "relation");
5471
if (isModified()) {
5572
xmlSerializer.attribute(null, "action", "modify");
5673
}
57-
setOsmElementXmlAttributes(xmlSerializer);
74+
setOsmElementXmlAttributes(xmlSerializer, omkOsmUser);
5875
// generate members
5976
setRelationXmlMembers(xmlSerializer);
6077
// generate tags
61-
super.xml(xmlSerializer);
78+
super.xml(xmlSerializer, omkOsmUser);
6279
xmlSerializer.endTag(null, "relation");
6380
}
6481

MapboxAndroidSDK/src/main/java/com/spatialdev/osm/model/OSMWay.java

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import com.mapbox.mapboxsdk.views.MapView;
88
import com.spatialdev.osm.renderer.OSMPath;
99

10+
import org.apache.commons.codec.binary.Hex;
11+
import org.apache.commons.codec.digest.DigestUtils;
1012
import org.xmlpull.v1.XmlSerializer;
1113

1214
import java.io.IOException;
@@ -61,19 +63,33 @@ public OSMWay(String idStr,
6163
}
6264

6365
@Override
64-
void xml(XmlSerializer xmlSerializer) throws IOException {
66+
public String checksum() {
67+
String str = preChecksum();
68+
return new String(Hex.encodeHex(DigestUtils.sha1(str)));
69+
}
70+
71+
public String preChecksum() {
72+
StringBuilder str = tagsAsSortedKVString();
73+
for (OSMNode n : linkedNodes) {
74+
str.append(n.checksum());
75+
}
76+
return str.toString();
77+
}
78+
79+
@Override
80+
void xml(XmlSerializer xmlSerializer, String omkOsmUser) throws IOException {
6581
for (OSMNode node : linkedNodes) {
66-
node.xml(xmlSerializer);
82+
node.xml(xmlSerializer, omkOsmUser);
6783
}
6884
xmlSerializer.startTag(null, "way");
69-
setOsmElementXmlAttributes(xmlSerializer);
85+
setOsmElementXmlAttributes(xmlSerializer, omkOsmUser);
7086
// generate nds
7187
setWayXmlNds(xmlSerializer);
7288
// generate tags
73-
super.xml(xmlSerializer);
89+
super.xml(xmlSerializer, omkOsmUser);
7490
xmlSerializer.endTag(null, "way");
7591
for (OSMRelation relation : linkedRelations) {
76-
relation.xml(xmlSerializer);
92+
relation.xml(xmlSerializer, omkOsmUser);
7793
}
7894
}
7995

@@ -102,14 +118,13 @@ int linkNodes(Map<Long, OSMNode> nodes, Set<Long> wayNodes) {
102118
// first check if the way is closed before doing this processing...
103119
checkIfClosed();
104120
LinkedList<Long> unlinkedRefs = new LinkedList<>();
105-
while (nodeRefs.size() > 0) {
106-
Long refId = nodeRefs.pop();
121+
for (Long refId : nodeRefs) {
107122
OSMNode node = nodes.get(refId);
108123
wayNodes.add(refId);
109124
if (node == null) {
110-
unlinkedRefs.push(refId);
125+
unlinkedRefs.add(refId);
111126
} else {
112-
linkedNodes.push(node);
127+
linkedNodes.add(node);
113128
}
114129
}
115130
nodeRefs = unlinkedRefs;

0 commit comments

Comments
 (0)