Browse code

Merge origin/master

Conflicts:
pom.xml

devnewton authored on 15/02/2014 at 12:48:55
Showing 13 changed files
... ...
@@ -1,3 +1,5 @@
1 1
 libtiled-jpurexml is a java library to parse [Tiled](http://www.mapeditor.org) tmx maps.
2 2
 
3
-It use [jpurexml](https://github.com/asilvestre/jpurexml), a pure java xml parser in order to be usable with [gwt](http://www.gwtproject.org/) compiler.
4 3
\ No newline at end of file
4
+It use [jpurexml](https://github.com/asilvestre/jpurexml), a pure java xml parser in order to be usable with [gwt](http://www.gwtproject.org/) compiler.
5
+
6
+Usage sample: [TestTmxLoader.java](src/test/java/im/bci/test/TestTmxLoader.java)
5 7
\ No newline at end of file
... ...
@@ -20,8 +20,7 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 20
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 21
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 22
 THE SOFTWARE. -->
23
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
24
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
23
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
25 24
     <modelVersion>4.0.0</modelVersion>
26 25
     <parent>
27 26
         <groupId>org.sonatype.oss</groupId>
... ...
@@ -30,7 +29,7 @@ THE SOFTWARE. -->
30 30
     </parent>
31 31
     <groupId>im.bci</groupId>
32 32
     <artifactId>libtiled-jpurexml</artifactId>
33
-    <version>0.2-SNAPSHOT</version>
33
+    <version>0.3-SNAPSHOT</version>
34 34
     <name>libtiled-jpurexml</name>
35 35
     <packaging>jar</packaging>
36 36
     <description>libtiled-jpurexml is a java library to parse [Tiled](http://www.mapeditor.org) tmx maps.</description>
... ...
@@ -39,7 +38,8 @@ THE SOFTWARE. -->
39 39
         <connection>scm:git:git@github.com:devnewton/libtiled-jpurexml.git</connection>
40 40
         <developerConnection>scm:git:git@github.com:devnewton/libtiled-jpurexml.git</developerConnection>
41 41
         <url>git@github.com:devnewton/libtiled-jpurexml.git</url>
42
-    </scm>
42
+      <tag>HEAD</tag>
43
+  </scm>
43 44
     <licenses>
44 45
         <license>
45 46
             <name>MIT</name>
... ...
@@ -63,6 +63,12 @@ THE SOFTWARE. -->
63 63
             <artifactId>jpurexml</artifactId>
64 64
             <version>0.10</version>
65 65
         </dependency>
66
+        <dependency>
67
+            <groupId>junit</groupId>
68
+            <artifactId>junit</artifactId>
69
+            <version>4.10</version>
70
+            <scope>test</scope>
71
+        </dependency>
66 72
     </dependencies>
67 73
     <build>
68 74
         <resources>
... ...
@@ -23,8 +23,6 @@
23 23
  */
24 24
 package im.bci.tmxloader;
25 25
 
26
-import java.util.Scanner;
27
-
28 26
 /**
29 27
  *
30 28
  * @author devnewton
... ...
@@ -51,24 +49,21 @@ public class TmxData {
51 51
     }
52 52
 
53 53
     public void decodeTo(int width, int height, int[][] data) {
54
-        switch (encoding) {
55
-            case "csv":
56
-                decodeCsvTo(width, height, data);
57
-                break;
58
-            default:
59
-                throw new RuntimeException(
60
-                        "Unsupported tiled layer data encoding: " + encoding);
54
+        if ("csv".equals(encoding)) {
55
+            decodeCsvTo(width, height, data);
56
+        } else {
57
+            throw new RuntimeException(
58
+                    "Unsupported tiled layer data encoding: " + encoding);
61 59
         }
62 60
     }
63 61
 
64 62
     private void decodeCsvTo(int width, int height, int[][] gidArray) {
65
-        try (Scanner scanner = new Scanner(this.data.trim())) {
66
-            scanner.useDelimiter("[\\s]*,[\\s]*");
67
-            for (int y = 0; y < height; ++y) {
68
-                for (int x = 0; x < width; ++x) {
69
-                    String str = scanner.next();
70
-                    gidArray[x][y] = Integer.parseInt(str);
71
-                }
63
+        String[] values = this.data.replaceAll("[\\s]", "").split(",");
64
+        int index = 0;
65
+        for (int y = 0; y < height; ++y) {
66
+            for (int x = 0; x < width; ++x) {
67
+                String str = values[index++];
68
+                gidArray[x][y] = Integer.parseInt(str);
72 69
             }
73 70
         }
74 71
     }
... ...
@@ -36,7 +36,7 @@ public class TmxLayer {
36 36
     private int x, y;
37 37
     private int width;
38 38
     private int height;
39
-    private List<TmxProperty> properties = new ArrayList<>();
39
+    private List<TmxProperty> properties = new ArrayList<TmxProperty>();
40 40
     private TmxData data;
41 41
     private TmxTileInstance tiles[][];
42 42
 
... ...
@@ -27,7 +27,6 @@ import com.github.asilvestre.jpurexml.XmlDoc;
27 27
 import com.github.asilvestre.jpurexml.XmlParseException;
28 28
 import com.github.asilvestre.jpurexml.XmlParser;
29 29
 import com.github.asilvestre.jpurexml.XmlTag;
30
-import java.io.IOException;
31 30
 import java.util.ArrayList;
32 31
 import java.util.EnumSet;
33 32
 import java.util.HashMap;
... ...
@@ -40,54 +39,28 @@ import java.util.ListIterator;
40 40
  */
41 41
 public class TmxLoader {
42 42
 
43
-    public TmxMap load(String xml) {
43
+    public void parseTmx(TmxMap map, String xml) {
44 44
         try {
45 45
             XmlDoc doc = XmlParser.parseXml(xml);
46
-            TmxMap map = new TmxMap();
47 46
             parseMap(doc.root, map);
48 47
             parseTilesets(doc.root, map);
49
-            parseExternalTilesets(map);
50
-            decodeLayerData(map);
51
-            return map;
52
-        } catch (XmlParseException | IOException ex) {
48
+        } catch (XmlParseException ex) {
53 49
             throw new RuntimeException("Cannot load tmx", ex);
54 50
         }
55 51
     }
56 52
 
57
-    private void parseMap(XmlTag xmlMap, TmxMap map) throws NumberFormatException {
58
-        map.setWidth(getMandatoryIntAttribute(xmlMap, "width"));
59
-        map.setHeight(getMandatoryIntAttribute(xmlMap, "height"));
60
-        map.setTilewidth(getMandatoryIntAttribute(xmlMap, "tilewidth"));
61
-        map.setTileheight(getMandatoryIntAttribute(xmlMap, "tileheight"));
62
-        map.setOrientation(TmxMapOrientation.valueOf(xmlMap.attributes.get("orientation").toUpperCase()));
63
-        map.setProperties(parseProperties(findChild(xmlMap, "properties")));
64
-        List<TmxLayer> layers = new ArrayList<>();
65
-        for (XmlTag child : xmlMap.children) {
66
-            if ("layer".equals(child.name)) {
67
-                TmxLayer layer = new TmxLayer();
68
-                parseLayer(child, layer);
69
-                layer.afterUnmarshal();
70
-                layers.add(layer);
71
-            }
72
-        }
73
-        map.setLayers(layers);
74
-    }
75
-
76
-    XmlTag findChild(XmlTag parent, String name) {
77
-        for (XmlTag child : parent.children) {
78
-            if (name.equals(child.name)) {
79
-                return child;
80
-            }
53
+    public void parseTsx(TmxMap map, TmxTileset tileset, String xml) {
54
+        try {
55
+            parseTileset(XmlParser.parseXml(xml).root, map, tileset);
56
+            tileset.afterUnmarshal();
57
+            tileset.setReady(true);
58
+        } catch (XmlParseException ex) {
59
+            throw new RuntimeException("Cannot load tmx", ex);
81 60
         }
82
-        return null;
83
-    }
84
-
85
-    protected String openExternalTileset(String source) {
86
-        throw new RuntimeException("Not implemented");
87 61
     }
88
-
89
-    private void decodeLayerData(TmxMap map) {
90
-        HashMap<TmxTileInstance, TmxTileInstance> tileInstancePool = new HashMap<>();
62
+    
63
+    public void decode(TmxMap map) {
64
+        HashMap<TmxTileInstance, TmxTileInstance> tileInstancePool = new HashMap<TmxTileInstance, TmxTileInstance>();
91 65
         for (TmxLayer layer : map.getLayers()) {
92 66
             int[][] data = new int[layer.getWidth()][layer.getHeight()];
93 67
             layer.getData().decodeTo(layer.getWidth(), layer.getHeight(), data);
... ...
@@ -114,31 +87,46 @@ public class TmxLoader {
114 114
                                     tileInstancePool.put(instance, instance);
115 115
                                 }
116 116
                                 layer.setTileAt(x, y, instance);
117
+                                break;
117 118
                             }
118 119
                         }
119 120
                     }
120 121
                 }
121 122
             }
122 123
         }
124
+        map.setReady(true);
123 125
     }
124 126
 
125
-    private void parseExternalTilesets(TmxMap map) throws IOException, XmlParseException {
126
-        for (TmxTileset tileset : map.getTilesets()) {
127
-            final String source = tileset.getSource();
128
-            if (null != source) {
129
-                parseTileset(XmlParser.parseXml(openExternalTileset(source)).root, map, tileset);
130
-                String tilesetDir = source.substring(0, source.lastIndexOf('/') + 1);
131
-                final TmxImage image = tileset.getImage();
132
-                if (null != image) {
133
-                    tileset.getImage().setSource(tilesetDir + image.getSource());
134
-                }
135
-                tileset.afterUnmarshal();
127
+    private void parseMap(XmlTag xmlMap, TmxMap map) throws NumberFormatException {
128
+        map.setWidth(getMandatoryIntAttribute(xmlMap, "width"));
129
+        map.setHeight(getMandatoryIntAttribute(xmlMap, "height"));
130
+        map.setTilewidth(getMandatoryIntAttribute(xmlMap, "tilewidth"));
131
+        map.setTileheight(getMandatoryIntAttribute(xmlMap, "tileheight"));
132
+        map.setOrientation(TmxMapOrientation.valueOf(xmlMap.attributes.get("orientation").toUpperCase()));
133
+        map.setProperties(parseProperties(findChild(xmlMap, "properties")));
134
+        List<TmxLayer> layers = new ArrayList<TmxLayer>();
135
+        for (XmlTag child : xmlMap.children) {
136
+            if ("layer".equals(child.name)) {
137
+                TmxLayer layer = new TmxLayer();
138
+                parseLayer(child, layer);
139
+                layer.afterUnmarshal();
140
+                layers.add(layer);
136 141
             }
137 142
         }
143
+        map.setLayers(layers);
144
+    }
145
+
146
+    private XmlTag findChild(XmlTag parent, String name) {
147
+        for (XmlTag child : parent.children) {
148
+            if (name.equals(child.name)) {
149
+                return child;
150
+            }
151
+        }
152
+        return null;
138 153
     }
139 154
 
140 155
     private List<TmxProperty> parseProperties(XmlTag xmlProperties) {
141
-        List<TmxProperty> properties = new ArrayList<>();
156
+        List<TmxProperty> properties = new ArrayList<TmxProperty>();
142 157
         if (null != xmlProperties) {
143 158
             for (XmlTag child : xmlProperties.children) {
144 159
                 if ("property".equals(child.name)) {
... ...
@@ -153,22 +141,22 @@ public class TmxLoader {
153 153
     }
154 154
 
155 155
     private void parseTilesets(XmlTag xmlMap, TmxMap map) throws XmlParseException {
156
-        List<TmxTileset> tilesets = new ArrayList<>();
156
+        List<TmxTileset> tilesets = new ArrayList<TmxTileset>();
157 157
         for (XmlTag child : xmlMap.children) {
158 158
             if ("tileset".equals(child.name)) {
159 159
                 TmxTileset tileset = new TmxTileset();
160 160
                 String source = child.attributes.get("source");
161
+                tileset.setFirstgid(getMandatoryIntAttribute(child, "firstgid"));
161 162
                 if (null != source) {
162
-                    tileset.setFirstgid(getMandatoryIntAttribute(child, "firstgid"));
163 163
                     tileset.setSource(source);
164 164
                 } else {
165 165
                     parseTileset(child, map, tileset);
166 166
                     tileset.afterUnmarshal();
167
+                    tileset.setReady(true);
167 168
                 }
168 169
                 tilesets.add(tileset);
169 170
             }
170 171
         }
171
-
172 172
         map.setTilesets(tilesets);
173 173
     }
174 174
 
... ...
@@ -180,7 +168,7 @@ public class TmxLoader {
180 180
         tileset.setTileheight(getIntAttribute(xmlTileset, "tileheight", map.getTileheight()));
181 181
         tileset.setProperties(parseProperties(findChild(xmlTileset, "properties")));
182 182
         tileset.setImage(parseImage(findChild(xmlTileset, "image")));
183
-        List<TmxTile> tiles = new ArrayList<>();
183
+        List<TmxTile> tiles = new ArrayList<TmxTile>();
184 184
         for (XmlTag child : xmlTileset.children) {
185 185
             if ("tile".equals(child.name)) {
186 186
                 tiles.add(parseTile(tileset, child));
... ...
@@ -32,14 +32,15 @@ import java.util.List;
32 32
  */
33 33
 public class TmxMap {
34 34
 
35
+    private boolean ready;
35 36
     private int width;
36 37
     private int height;
37 38
     private int tilewidth;
38 39
     private int tileheight;
39 40
     private TmxMapOrientation orientation;
40
-    private List<TmxTileset> tilesets = new ArrayList<>();
41
-    private List<TmxProperty> properties = new ArrayList<>();
42
-    private List<TmxLayer> layers = new ArrayList<>();
41
+    private List<TmxTileset> tilesets = new ArrayList<TmxTileset>();
42
+    private List<TmxProperty> properties = new ArrayList<TmxProperty>();
43
+    private List<TmxLayer> layers = new ArrayList<TmxLayer>();
43 44
 
44 45
     public TmxMapOrientation getOrientation() {
45 46
         return orientation;
... ...
@@ -108,4 +109,21 @@ public class TmxMap {
108 108
     public String getProperty(String name, String defaultValue) {
109 109
         return TmxUtils.getProperty(properties, name, defaultValue);
110 110
     }
111
+
112
+    public boolean isReady() {
113
+        return ready;
114
+    }
115
+
116
+    public void setReady(boolean ready) {
117
+        this.ready = ready;
118
+    }
119
+    
120
+    public boolean canDecode() {
121
+        for(TmxTileset ts : tilesets) {
122
+            if(!ts.isReady()) {
123
+                return false;
124
+            }
125
+        }
126
+        return true;
127
+    }
111 128
 }
... ...
@@ -33,7 +33,7 @@ import java.util.List;
33 33
 public class TmxTile {
34 34
 
35 35
     private int id;
36
-    private List<TmxProperty> properties = new ArrayList<>();
36
+    private List<TmxProperty> properties = new ArrayList<TmxProperty>();
37 37
     private TmxFrame frame;
38 38
 
39 39
     public int getId() {
... ...
@@ -24,8 +24,6 @@
24 24
 package im.bci.tmxloader;
25 25
 
26 26
 import java.util.EnumSet;
27
-import java.util.Objects;
28
-
29 27
 /**
30 28
  *
31 29
  * @author devnewton
... ...
@@ -51,8 +49,8 @@ public class TmxTileInstance {
51 51
     @Override
52 52
     public int hashCode() {
53 53
         int hash = 7;
54
-        hash = 89 * hash + Objects.hashCode(this.tile);
55
-        hash = 89 * hash + Objects.hashCode(this.effect);
54
+        hash = 89 * hash + (this.tile != null ? this.tile.hashCode() : 0);
55
+        hash = 89 * hash + (this.effect != null ? this.effect.hashCode() : 0);
56 56
         return hash;
57 57
     }
58 58
 
... ...
@@ -65,10 +63,10 @@ public class TmxTileInstance {
65 65
             return false;
66 66
         }
67 67
         final TmxTileInstance other = (TmxTileInstance) obj;
68
-        if (!Objects.equals(this.tile, other.tile)) {
68
+        if (!TmxUtils.equals(this.tile, other.tile)) {
69 69
             return false;
70 70
         }
71
-        if (!Objects.equals(this.effect, other.effect)) {
71
+        if (!TmxUtils.equals(this.effect, other.effect)) {
72 72
             return false;
73 73
         }
74 74
         return true;
... ...
@@ -38,12 +38,20 @@ public class TmxTileset {
38 38
     private int tilewidth;
39 39
     private int tileheight;
40 40
     private int spacing, margin;
41
-    private List<TmxProperty> properties = new ArrayList<>();
41
+    private List<TmxProperty> properties = new ArrayList<TmxProperty>();
42 42
     private TmxImage image;
43 43
     private int firstgid;
44
-    private final TreeMap<Integer/*id*/, TmxTile> tilesById = new TreeMap<>();
45
-    private List<TmxTile> tiles = new ArrayList<>();
44
+    private final TreeMap<Integer/*id*/, TmxTile> tilesById = new TreeMap<Integer/*id*/, TmxTile>();
45
+    private List<TmxTile> tiles = new ArrayList<TmxTile>();
46
+    private boolean ready;
47
+    
48
+    public boolean isReady() {
49
+        return ready;
50
+    }
46 51
 
52
+    public void setReady(boolean ready) {
53
+        this.ready = ready;
54
+    }
47 55
     public String getSource() {
48 56
         return source;
49 57
     }
... ...
@@ -42,4 +42,8 @@ public class TmxUtils {
42 42
         }
43 43
         return defaultValue;
44 44
     }
45
+    
46
+    public static boolean equals(Object a, Object b) {
47
+        return (a == b) || (a != null && a.equals(b));
48
+    }
45 49
 }
46 50
new file mode 100644
... ...
@@ -0,0 +1,88 @@
0
+/*
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 devnewton <devnewton@bci.im>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+ */
23
+package im.bci.test;
24
+
25
+import im.bci.tmxloader.TmxLoader;
26
+import im.bci.tmxloader.TmxMap;
27
+import im.bci.tmxloader.TmxTile;
28
+import im.bci.tmxloader.TmxTileset;
29
+import java.io.File;
30
+import java.io.FileInputStream;
31
+import java.io.IOException;
32
+import java.io.InputStream;
33
+import java.util.Scanner;
34
+import org.junit.Test;
35
+import org.junit.Assert;
36
+
37
+/**
38
+ *
39
+ * @author devnewton
40
+ */
41
+public class TestTmxLoader {
42
+
43
+    @Test
44
+    public void simpleTmx() throws IOException {
45
+        final File mapFile = new File("test-data/desert.tmx");
46
+        final File mapParentDir = mapFile.getParentFile().getCanonicalFile();
47
+        TmxLoader loader = new TmxLoader();
48
+        TmxMap map = new TmxMap();
49
+        loader.parseTmx(map, loadText(mapFile));
50
+        for (TmxTileset tileset : map.getTilesets()) {
51
+            File tilesetParentDir;
52
+            if (null != tileset.getSource()) {
53
+                final File tilesetFile = new File(mapParentDir, tileset.getSource());
54
+                tilesetParentDir = tilesetFile.getParentFile().getCanonicalFile();
55
+                loader.parseTsx(map, tileset, loadText(tilesetFile));
56
+            } else {
57
+                tilesetParentDir = mapParentDir;
58
+            }
59
+            if (null != tileset.getImage()) {
60
+                tileset.getImage().setSource(convertRelativeToAbsolutePath(tilesetParentDir, tileset.getImage().getSource()));
61
+            }
62
+            for (TmxTile tile : tileset.getTiles()) {
63
+                tile.getFrame().getImage().setSource(convertRelativeToAbsolutePath(tilesetParentDir, tile.getFrame().getImage().getSource()));
64
+            }
65
+        }
66
+        loader.decode(map);
67
+
68
+        Assert.assertEquals(40, map.getWidth());
69
+        Assert.assertEquals(40, map.getHeight());
70
+        Assert.assertEquals(32, map.getTilewidth());
71
+        Assert.assertEquals(32, map.getTileheight());
72
+        Assert.assertEquals(1, map.getLayers().size());
73
+    }
74
+    
75
+    private String convertRelativeToAbsolutePath(File parentDir, String relativePath) throws IOException {
76
+        if(new File(relativePath).isAbsolute()) {
77
+            return relativePath;
78
+        }
79
+        return new File(parentDir, relativePath).getCanonicalPath();        
80
+    }
81
+
82
+    private String loadText(File f) throws IOException {
83
+        try (InputStream is = new FileInputStream(f); Scanner s = new Scanner(is, "UTF-8").useDelimiter("\\Z")) {
84
+            return s.next();
85
+        }
86
+    }
87
+}
0 88
new file mode 100644
... ...
@@ -0,0 +1,50 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
1
+<map version="1.0" orientation="orthogonal" width="40" height="40" tilewidth="32" tileheight="32">
2
+ <tileset firstgid="1" name="Desert" tilewidth="32" tileheight="32" spacing="1" margin="1">
3
+  <image source="tmw_desert_spacing.png" width="265" height="199"/>
4
+ </tileset>
5
+ <layer name="Ground" width="40" height="40">
6
+  <data encoding="csv">
7
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,14,15,16,30,30,30,30,30,30,30,30,30,30,30,30,30,
8
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,46,14,15,16,30,31,30,30,30,30,30,30,30,30,30,30,30,
9
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,14,15,16,30,30,30,30,30,30,30,30,30,30,30,30,30,
10
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,22,23,24,30,30,30,30,30,30,30,30,30,30,30,30,30,
11
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,1,2,3,30,30,31,30,30,30,30,30,30,30,30,30,30,
12
+30,30,30,30,30,30,30,30,30,30,30,25,26,26,26,26,26,26,26,26,26,26,26,27,9,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
13
+30,30,30,30,30,30,30,30,30,30,30,33,34,34,34,34,34,34,34,34,34,34,34,35,9,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
14
+30,30,30,30,30,30,40,30,30,30,30,33,34,36,42,37,34,34,34,34,34,34,34,35,9,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
15
+30,30,30,30,30,30,30,30,30,30,30,33,34,35,30,33,34,34,34,34,34,34,34,35,9,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
16
+30,30,30,30,30,30,30,30,38,30,30,33,34,35,30,33,34,34,34,34,34,34,34,35,9,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
17
+30,30,30,30,30,48,38,30,30,30,30,33,34,44,26,45,34,34,34,34,34,34,34,35,9,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
18
+30,30,30,40,30,30,30,40,30,30,30,33,34,34,34,34,34,34,34,36,42,37,34,35,9,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
19
+40,30,30,30,30,40,38,30,30,38,30,33,34,34,34,34,34,34,34,44,26,45,34,35,9,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
20
+30,39,30,30,30,38,30,40,30,30,30,33,34,34,34,34,34,34,34,34,34,34,34,35,9,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
21
+30,30,30,39,30,30,30,30,30,30,30,41,42,42,42,42,42,42,42,42,42,42,42,43,9,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
22
+7,7,8,1,2,2,2,2,2,2,2,2,3,1,2,2,2,2,2,2,2,2,2,2,29,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
23
+15,15,16,9,10,10,10,10,10,10,10,10,11,9,10,10,10,10,10,10,10,10,10,10,10,10,11,30,30,30,30,30,30,30,30,30,30,30,30,30,
24
+23,23,24,17,18,18,18,18,18,18,18,18,19,17,18,18,18,18,18,18,18,18,18,18,18,18,19,30,30,30,30,30,30,30,30,30,30,30,30,30,
25
+30,30,39,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,32,31,
26
+30,30,30,30,39,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,32,
27
+39,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,25,26,26,26,26,26,26,26,26,26,26,26,27,30,
28
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,46,30,33,34,34,34,34,34,34,34,34,36,42,37,35,30,
29
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,33,34,34,34,34,34,34,34,34,35,48,33,35,30,
30
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,47,33,34,34,34,34,34,34,34,34,35,48,33,35,30,
31
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,39,30,30,30,33,34,34,34,34,34,34,34,34,35,48,33,35,30,
32
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,33,34,34,34,34,34,34,34,34,44,26,45,35,30,
33
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,47,30,33,34,34,34,34,34,34,34,34,34,34,34,35,30,
34
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,33,34,34,34,34,34,34,34,34,34,34,34,35,48,
35
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,33,34,34,34,34,34,34,34,34,34,34,34,35,30,
36
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,41,42,42,42,42,42,42,42,42,42,42,42,43,30,
37
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
38
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,32,30,30,30,
39
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
40
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,32,30,30,30,31,30,30,30,30,
41
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,32,30,30,
42
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
43
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
44
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
45
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
46
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30
47
+</data>
48
+ </layer>
49
+</map>
0 50
new file mode 100644
1 51
Binary files /dev/null and b/test-data/tmw_desert_spacing.png differ