Class: KMLMaker

Inherits:
Visitor show all
Includes:
KMLUtils
Defined in:
lib/kml_maker.rb

Overview

Convert SITAC objects into KML code

Version:

  • 1.1.0

Constant Summary

Constants included from LogUtils

LogUtils::Log

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from KMLUtils

#create_circle, #create_ellipse, #create_line, #meters_to_degrees

Constructor Details

#initializeKMLMaker

Returns a new instance of KMLMaker.



144
145
146
147
# File 'lib/kml_maker.rb', line 144

def initialize
  super
  @figures = []
end

Instance Attribute Details

#contentObject (readonly)

Returns the value of attribute content.



142
143
144
# File 'lib/kml_maker.rb', line 142

def content
  @content
end

#nameObject (readonly)

Returns the value of attribute name.



142
143
144
# File 'lib/kml_maker.rb', line 142

def name
  @name
end

Instance Method Details

#build(figures, name = "SITAC_#{Time.now.strftime('%Y%m%d%H%M%S')}") ⇒ String

build the kml file

Parameters:

  • figures (Array<Figure>)

    the list of figures to convert

  • name (String) (defaults to: "SITAC_#{Time.now.strftime('%Y%m%d%H%M%S')}")

    the name of the kml file

Returns:

  • (String)

    the kml code



153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/kml_maker.rb', line 153

def build(figures, name = "SITAC_#{Time.now.strftime('%Y%m%d%H%M%S')}")
  @figures = figures
  @name = name
  header
  @figures.each do |figure|
    next if figure.nil?

    figure.accept(self)
  end
  footer
  Log.succ("Successfully built KML code for SITAC #{@name}! It is #{@content.count("\n")} lines long.",
           'CoMe_KMLMaker')
end

#export(dirname) ⇒ String

export the kml file

Parameters:

  • dirname (String)

    the name of the kml file

Returns:

  • (String)

    the name of the kml file



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/kml_maker.rb', line 170

def export(dirname)
  # create file
  time = Time.now.strftime('%Y%m%d%H%M%S')
  file = "#{dirname}/#{@name}_#{time}.kml"
  kml_file = File.open(file, 'w')
  kml_file.write(@content)
  kml_file.close
  Log.info("Successfully exported KML file #{file}!", 'CoMe_KMLMaker')

  file
rescue StandardError => e
  # The directory does not exist, we create it
  if e.message.include?('No such file or directory')
    # create dir
    dir = File.dirname(file)
    Dir.mkdir(dir) unless File.exist?(dir)
    retry
  end
  Log.err("Cannot create KML file #{filename}! Got error #{e}", 'CoMe_KMLMaker')
end

Generate the footer of the kml file



203
204
205
206
207
# File 'lib/kml_maker.rb', line 203

def footer
  ftr = "</Document>
        </kml>"
  @content += ftr
end

#headerObject

Generate the header of the kml file



192
193
194
195
196
197
198
199
200
# File 'lib/kml_maker.rb', line 192

def header
  hdr_kml = '<?xml version="1.0" encoding="UTF-8"?>
              <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
              <Document>'
  hdr_kml += "<name>#{@name}</name>"
  hdr_file = File.open('lib/raw/styles_sitac.xml', 'r')
  hdr_kml += hdr_file.read.to_s
  @content += hdr_kml
end

#visit_bullseye(bullseye) ⇒ Object

Add a Bullseye to the kml file

Parameters:

  • bullseye (Bullseye)

    the bullseye to add



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/kml_maker.rb', line 274

def visit_bullseye(bullseye)
  nil unless bullseye.rings.positive?

  points_thick = []
  points_thin = []

  nb_rings = bullseye.rings
  distance = meters_to_degrees(bullseye.ring_distance) / 2
  radius = meters_to_degrees(bullseye.vradius)
  smallest_radius = radius - (nb_rings * distance)
  center_coords = [bullseye.center.latitude, bullseye.center.longitude]
  # thick lines (main rings, every 2 rings)
  (0..nb_rings).step(2) do |i|
    rad = smallest_radius + i * distance
    points_thick << create_circle(center_coords, rad)
  end
  # thin lines (every other ring)
  (1..nb_rings).step(2) do |i|
    rad = smallest_radius + i * distance
    points_thin << create_circle(center_coords, rad)
  end

  # Build main circles
  kml_bullseye_main = "<Placemark>
                  <name>#{bullseye.name}</name>
                  <styleUrl>#style_bulls</styleUrl>
                  <MultiGeometry>"
  points_thick.each do |point|
    kml_bullseye_main += '<Polygon><outerBoundaryIs><LinearRing><coordinates>'
    point.each do |pt|
      kml_bullseye_main += "#{pt[1]},#{pt[0]},0\n"
    end
    kml_bullseye_main += '</coordinates></LinearRing></outerBoundaryIs></Polygon>'
  end
  kml_bullseye_main += '</MultiGeometry></Placemark>'

  # Build secondary circles
  kml_bulls_secondary = "<Placemark>
                  <name>#{bullseye.name}_second</name>
                  <styleUrl>#style_bulls_thin</styleUrl>
                  <MultiGeometry>"
  points_thin.each do |point|
    kml_bulls_secondary += '<Polygon><outerBoundaryIs><LinearRing><coordinates>'
    point.each do |pt|
      kml_bulls_secondary += "#{pt[1]},#{pt[0]},0\n"
    end
    kml_bulls_secondary += '</coordinates></LinearRing></outerBoundaryIs></Polygon>'
  end
  kml_bulls_secondary += '</MultiGeometry></Placemark>'

  # Build lines
  kml_bulls_cross = "<Placemark>
                  <name>#{bullseye.name}_lines</name>
                  <styleUrl>#style_line</styleUrl>
                  <MultiGeometry>"
  n = 45
  (0..360).step(n) do |i|
    kml_bulls_cross += "<LineString>
                    <coordinates>"
    pt_cross = create_line(center_coords, radius, i)
    pt_cross.each do |pt|
      kml_bulls_cross += "#{pt[1]},#{pt[0]},0\n"
    end
    kml_bulls_cross += '</coordinates></LineString>'
  end

  kml_bulls_cross += '</MultiGeometry></Placemark>'
  @content += kml_bullseye_main + kml_bulls_secondary + kml_bulls_cross
end

#visit_corridor(corridor) ⇒ Object

Add a corridor to the kml file

Parameters:

  • corridor (Corridor)

    the corridor to add



372
373
374
# File 'lib/kml_maker.rb', line 372

def visit_corridor(corridor)
  nil # TODO
end

#visit_ellipse(ellipse) ⇒ Object

Add an ellipse to the kml file

Parameters:

  • ellipse (Ellipse)

    the ellipse to add



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/kml_maker.rb', line 346

def visit_ellipse(ellipse)
  h_radius = meters_to_degrees(ellipse.hradius)
  v_radius = meters_to_degrees(ellipse.vradius)
  center = [ellipse.center.latitude, ellipse.center.longitude]
  points = create_ellipse(center, h_radius, v_radius)

  kml_ellipse = "<Placemark>
                  <name>#{ellipse.name}</name>
                  <styleUrl>#style_circle</styleUrl>
                  <Polygon>
                    <outerBoundaryIs>
                      <LinearRing>
                        <coordinates>"
  points.each do |point|
    kml_ellipse += "#{point[1]},#{point[0]},0\n"
  end
  kml_ellipse += "</coordinates>
                  </LinearRing>
                </outerBoundaryIs>
              </Polygon>
            </Placemark>"
  @content += kml_ellipse
end

#visit_line(line) ⇒ Object

Add a line to the kml file

Parameters:

  • line (Line)

    the line to add



224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/kml_maker.rb', line 224

def visit_line(line)
  kml_line = "<Placemark>
                <name>#{line.name}</name>
                <styleUrl>#style_line</styleUrl>
                <LineString>
                  <coordinates>"
  line.points.each do |point|
    kml_line += "#{point.longitude},#{point.latitude},0 "
  end
  kml_line += "</coordinates>
                </LineString>
              </Placemark>"
  @content += kml_line
end

#visit_point(point) ⇒ Object

Add a point to the kml file

Parameters:

  • point (Point)

    the point to add



211
212
213
214
215
216
217
218
219
220
# File 'lib/kml_maker.rb', line 211

def visit_point(point)
  kml_point = "<Placemark>
                  <name>#{point.name}</name>
                  <styleUrl>#style_placemark</styleUrl>
                  <Point>
                    <coordinates>#{point.longitude},#{point.latitude},0</coordinates>
                  </Point>
                </Placemark>"
  @content += kml_point
end

#visit_polygon(polygon) ⇒ Object

Add a polygon to the kml file

Parameters:

  • polygon (Polygon)

    the polygon to add



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/kml_maker.rb', line 241

def visit_polygon(polygon)
  polygon.points << polygon.points[0] if polygon.points[-1] != polygon.points[0]
  kml_poly = "<Placemark>
              <name>#{polygon.name}</name>
              <styleUrl>#style_shape</styleUrl>
              <Polygon>
                <outerBoundaryIs>
                  <LinearRing>
                    <coordinates>"
  polygon.points.each do |point|
    kml_poly += "#{point.longitude},#{point.latitude},0\n"
  end
  kml_poly += '</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark>'
  @content += kml_poly
end

#visit_rectangle(rectangle) ⇒ Object

Add a rectangle to the kml file

Parameters:

  • rectangle (Rectangle)

    the rectangle to add



259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/kml_maker.rb', line 259

def visit_rectangle(rectangle)
  start_point = rectangle.start
  rect_points = []
  rect_points << start_point
  rect_points << Point.new('', start_point.latitude + meters_to_degrees(rectangle.vertical), start_point.longitude)
  rect_points << Point.new('', start_point.latitude + meters_to_degrees(rectangle.vertical),
                           start_point.longitude + meters_to_degrees(rectangle.horizontal))
  rect_points << Point.new('', start_point.latitude, start_point.longitude + meters_to_degrees(rectangle.horizontal))
  rect_points << start_point

  visit_polygon(Polygon.new(rectangle.name, rect_points))
end