Project

General

Profile

Download (10.2 KB) Statistics
| Branch: | Tag: | Revision:
1
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
2
 * full list of contributors). Published under the 2-clause BSD license.
3
 * See license.txt in the OpenLayers distribution or repository for the
4
 * full text of the license. */
5

    
6
/**
7
 * @requires OpenLayers/Geometry/Collection.js
8
 * @requires OpenLayers/Geometry/LineString.js
9
 */
10

    
11
/**
12
 * Class: OpenLayers.Geometry.MultiLineString
13
 * A MultiLineString is a geometry with multiple <OpenLayers.Geometry.LineString>
14
 * components.
15
 * 
16
 * Inherits from:
17
 *  - <OpenLayers.Geometry.Collection>
18
 *  - <OpenLayers.Geometry> 
19
 */
20
OpenLayers.Geometry.MultiLineString = OpenLayers.Class(
21
  OpenLayers.Geometry.Collection, {
22

    
23
    /**
24
     * Property: componentTypes
25
     * {Array(String)} An array of class names representing the types of
26
     * components that the collection can include.  A null value means the
27
     * component types are not restricted.
28
     */
29
    componentTypes: ["OpenLayers.Geometry.LineString"],
30

    
31
    /**
32
     * Constructor: OpenLayers.Geometry.MultiLineString
33
     * Constructor for a MultiLineString Geometry.
34
     *
35
     * Parameters: 
36
     * components - {Array(<OpenLayers.Geometry.LineString>)} 
37
     *
38
     */
39
    
40
    /**
41
     * Method: split
42
     * Use this geometry (the source) to attempt to split a target geometry.
43
     * 
44
     * Parameters:
45
     * geometry - {<OpenLayers.Geometry>} The target geometry.
46
     * options - {Object} Properties of this object will be used to determine
47
     *     how the split is conducted.
48
     *
49
     * Valid options:
50
     * mutual - {Boolean} Split the source geometry in addition to the target
51
     *     geometry.  Default is false.
52
     * edge - {Boolean} Allow splitting when only edges intersect.  Default is
53
     *     true.  If false, a vertex on the source must be within the tolerance
54
     *     distance of the intersection to be considered a split.
55
     * tolerance - {Number} If a non-null value is provided, intersections
56
     *     within the tolerance distance of an existing vertex on the source
57
     *     will be assumed to occur at the vertex.
58
     * 
59
     * Returns:
60
     * {Array} A list of geometries (of this same type as the target) that
61
     *     result from splitting the target with the source geometry.  The
62
     *     source and target geometry will remain unmodified.  If no split
63
     *     results, null will be returned.  If mutual is true and a split
64
     *     results, return will be an array of two arrays - the first will be
65
     *     all geometries that result from splitting the source geometry and
66
     *     the second will be all geometries that result from splitting the
67
     *     target geometry.
68
     */
69
    split: function(geometry, options) {
70
        var results = null;
71
        var mutual = options && options.mutual;
72
        var splits, sourceLine, sourceLines, sourceSplit, targetSplit;
73
        var sourceParts = [];
74
        var targetParts = [geometry];
75
        for(var i=0, len=this.components.length; i<len; ++i) {
76
            sourceLine = this.components[i];
77
            sourceSplit = false;
78
            for(var j=0; j < targetParts.length; ++j) { 
79
                splits = sourceLine.split(targetParts[j], options);
80
                if(splits) {
81
                    if(mutual) {
82
                        sourceLines = splits[0];
83
                        for(var k=0, klen=sourceLines.length; k<klen; ++k) {
84
                            if(k===0 && sourceParts.length) {
85
                                sourceParts[sourceParts.length-1].addComponent(
86
                                    sourceLines[k]
87
                                );
88
                            } else {
89
                                sourceParts.push(
90
                                    new OpenLayers.Geometry.MultiLineString([
91
                                        sourceLines[k]
92
                                    ])
93
                                );
94
                            }
95
                        }
96
                        sourceSplit = true;
97
                        splits = splits[1];
98
                    }
99
                    if(splits.length) {
100
                        // splice in new target parts
101
                        splits.unshift(j, 1);
102
                        Array.prototype.splice.apply(targetParts, splits);
103
                        break;
104
                    }
105
                }
106
            }
107
            if(!sourceSplit) {
108
                // source line was not hit
109
                if(sourceParts.length) {
110
                    // add line to existing multi
111
                    sourceParts[sourceParts.length-1].addComponent(
112
                        sourceLine.clone()
113
                    );
114
                } else {
115
                    // create a fresh multi
116
                    sourceParts = [
117
                        new OpenLayers.Geometry.MultiLineString(
118
                            sourceLine.clone()
119
                        )
120
                    ];
121
                }
122
            }
123
        }
124
        if(sourceParts && sourceParts.length > 1) {
125
            sourceSplit = true;
126
        } else {
127
            sourceParts = [];
128
        }
129
        if(targetParts && targetParts.length > 1) {
130
            targetSplit = true;
131
        } else {
132
            targetParts = [];
133
        }
134
        if(sourceSplit || targetSplit) {
135
            if(mutual) {
136
                results = [sourceParts, targetParts];
137
            } else {
138
                results = targetParts;
139
            }
140
        }
141
        return results;
142
    },
143
    
144
    /**
145
     * Method: splitWith
146
     * Split this geometry (the target) with the given geometry (the source).
147
     *
148
     * Parameters:
149
     * geometry - {<OpenLayers.Geometry>} A geometry used to split this
150
     *     geometry (the source).
151
     * options - {Object} Properties of this object will be used to determine
152
     *     how the split is conducted.
153
     *
154
     * Valid options:
155
     * mutual - {Boolean} Split the source geometry in addition to the target
156
     *     geometry.  Default is false.
157
     * edge - {Boolean} Allow splitting when only edges intersect.  Default is
158
     *     true.  If false, a vertex on the source must be within the tolerance
159
     *     distance of the intersection to be considered a split.
160
     * tolerance - {Number} If a non-null value is provided, intersections
161
     *     within the tolerance distance of an existing vertex on the source
162
     *     will be assumed to occur at the vertex.
163
     * 
164
     * Returns:
165
     * {Array} A list of geometries (of this same type as the target) that
166
     *     result from splitting the target with the source geometry.  The
167
     *     source and target geometry will remain unmodified.  If no split
168
     *     results, null will be returned.  If mutual is true and a split
169
     *     results, return will be an array of two arrays - the first will be
170
     *     all geometries that result from splitting the source geometry and
171
     *     the second will be all geometries that result from splitting the
172
     *     target geometry.
173
     */
174
    splitWith: function(geometry, options) {
175
        var results = null;
176
        var mutual = options && options.mutual;
177
        var splits, targetLine, sourceLines, sourceSplit, targetSplit, sourceParts, targetParts;
178
        if(geometry instanceof OpenLayers.Geometry.LineString) {
179
            targetParts = [];
180
            sourceParts = [geometry];
181
            for(var i=0, len=this.components.length; i<len; ++i) {
182
                targetSplit = false;
183
                targetLine = this.components[i];
184
                for(var j=0; j<sourceParts.length; ++j) {
185
                    splits = sourceParts[j].split(targetLine, options);
186
                    if(splits) {
187
                        if(mutual) {
188
                            sourceLines = splits[0];
189
                            if(sourceLines.length) {
190
                                // splice in new source parts
191
                                sourceLines.unshift(j, 1);
192
                                Array.prototype.splice.apply(sourceParts, sourceLines);
193
                                j += sourceLines.length - 2;
194
                            }
195
                            splits = splits[1];
196
                            if(splits.length === 0) {
197
                                splits = [targetLine.clone()];
198
                            }
199
                        }
200
                        for(var k=0, klen=splits.length; k<klen; ++k) {
201
                            if(k===0 && targetParts.length) {
202
                                targetParts[targetParts.length-1].addComponent(
203
                                    splits[k]
204
                                );
205
                            } else {
206
                                targetParts.push(
207
                                    new OpenLayers.Geometry.MultiLineString([
208
                                        splits[k]
209
                                    ])
210
                                );
211
                            }
212
                        }
213
                        targetSplit = true;                    
214
                    }
215
                }
216
                if(!targetSplit) {
217
                    // target component was not hit
218
                    if(targetParts.length) {
219
                        // add it to any existing multi-line
220
                        targetParts[targetParts.length-1].addComponent(
221
                            targetLine.clone()
222
                        );
223
                    } else {
224
                        // or start with a fresh multi-line
225
                        targetParts = [
226
                            new OpenLayers.Geometry.MultiLineString([
227
                                targetLine.clone()
228
                            ])
229
                        ];
230
                    }
231
                    
232
                }
233
            }
234
        } else {
235
            results = geometry.split(this);
236
        }
237
        if(sourceParts && sourceParts.length > 1) {
238
            sourceSplit = true;
239
        } else {
240
            sourceParts = [];
241
        }
242
        if(targetParts && targetParts.length > 1) {
243
            targetSplit = true;
244
        } else {
245
            targetParts = [];
246
        }
247
        if(sourceSplit || targetSplit) {
248
            if(mutual) {
249
                results = [sourceParts, targetParts];
250
            } else {
251
                results = targetParts;
252
            }
253
        }
254
        return results;
255
    },
256

    
257
    CLASS_NAME: "OpenLayers.Geometry.MultiLineString"
258
});
(5-5/9)