Water rights management system for Riley Water Consulting
# app/services/kml_parser.rb
class KmlParser
def initialize(id, model_name)
@id = id
@model_name = model_name.constantize
end
def parse_polygon
model = get_model
doc = open_doc(model)
coordinates_array = parse_coordinates(doc.at_css("polygon coordinates").text)
polygon =
{
type: "Polygon",
coordinates: [
coordinates_array
]
}
model.update_column(:polygon, polygon)
end
def parse_point
model = get_model
doc = open_doc(model)
coordinates_set = parse_coordinates(doc.at_css("point coordinates").text)
point =
{
type: "Point",
coordinates: coordinates_set[0]
}
model.update_column(:point, point)
end
private
def get_model
@model_name.find(@id)
end
def open_doc(model)
Nokogiri::HTML(open(model.kml.url))
end
def parse_coordinates(coordinates)
coordinates.scan(/(-?\d+.\d+),(-?\d+.\d+)/).collect { |lon, lat| [lon.to_f, lat.to_f]}
end
end
# app/helpers/application_helper.rb
def static_map(geometry)
# If polygon, encode polygon and attach to URL
if geometry["type"] == "Polygon"
encoded_poly = encode_polygon(geometry)
image_tag URI.encode("https://maps.googleapis.com/maps/api/staticmap?key=#{google_maps_api_key}&size=200x200&path=fillcolor:0x00000077|color:0x000000FF|weight:2|enc:#{encoded_poly}")
# If point, just attach point in lat,lon format
elsif geometry["type"] == "Point"
point = "#{geometry["coordinates"][1]},#{geometry["coordinates"][0]}"
image_tag URI.encode("https://maps.googleapis.com/maps/api/staticmap?key=#{google_maps_api_key}&size=200x200&zoom=14&markers=#{point}")
end
end
def encode_polygon(poly)
coordinates = []
# If more than 200 points in polygon, then simplify polygon
if poly["coordinates"][0].length > 200
simple_coordinates = simplify_coordinates(poly["coordinates"][0])
# Parse coordinates into expected format for encode method
simple_coordinates.each do |c|
coordinates << [c[:y], c[:x]]
end
# If less than 200 points in polygon, just parse into expected format for encode method
else
poly["coordinates"][0].each do |c|
coordinates << [c[1], c[0]]
end
end
# Encode points using Google encoded polyline algorithm
Polylines::Encoder.encode_points(coordinates)
end
def simplify_coordinates(coordinates)
# Parse coordinates into expected format for simplify method
coordinates_hash = []
coordinates.each do |c|
coordinates_hash << {x: c[0], y: c[1]}
end
# Simplify coordinates using tolerance: 0.001
SimplifyRb.simplify(coordinates_hash, 0.001)
end
ruby -v # 2.4.1
rails -v # 5.1.3
Install dependencies
bundle install
Create .env
file in project’s root directory (to easily get a SECRET_KEY_BASE
run rake secret
)
RACK_ENV=development
SECRET_KEY_BASE=secret-key-base
S3_BUCKET_NAME=s3-bucket-name
AWS_ACCESS_KEY_ID=aws-id
AWS_SECRET_ACCESS_KEY=aws-secret-key
GOOGLE_MAPS_KEY=google-maps-key
SENDGRID_USERNAME=sendgrid-username
SENDGRID_PASSWORD=sendgrid-password
Setup database
rake db:setup
Run server
foreman start