diff --git a/.gitignore b/.gitignore
index 48fb168f..7af77682 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,12 +6,27 @@
# Ignore bundler config.
/.bundle
+vendor/bundle
+coverage/
# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
+.DS_Store
# Ignore Byebug command history file.
.byebug_history
+
+# Ignore coverage reports
+coverage
+
+# Ignore public compiled assets
+public/assets/
+
+# Ignore .env configuration
+.env*
+
+# Ignore schema
+db/schema.rb
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 00000000..279202f2
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,27 @@
+AllCops:
+ Exclude:
+ - 'db/schema.rb'
+
+Metrics/LineLength:
+ Max: 199
+
+Style/BlockComments:
+ Enabled: false
+
+Style/EmptyMethod:
+ Enabled: false
+
+Style/Encoding:
+ Enabled: false
+
+Style/FrozenStringLiteralComment:
+ Enabled: false
+
+Style/LeadingCommentSpace:
+ Enabled: false
+
+Style/SpaceInsideBrackets:
+ Enabled: false
+
+Style/StringLiterals:
+ Enabled: false
diff --git a/.ruby-version b/.ruby-version
index 2bf1c1cc..0bee604d 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.3.1
+2.3.3
diff --git a/Gemfile b/Gemfile
index 4c7e5d3b..32fbd40e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,20 +1,25 @@
source 'https://rubygems.org'
-
gem 'coffee-rails', '~> 4.2' # Use CoffeeScript for .coffee assets and views
+gem 'dotenv-rails' # Use dotenv to load environment variables
+gem 'excon-rails' # Use excon rails for http requests
+gem 'font-awesome-rails', '>= 4.7.0' # Use Font Awesome for CSS Icons
+gem 'i18n-js', ">= 3.0.0.rc15" #extend i18n support directly into JS
gem 'jbuilder', '~> 2.5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jquery-rails' # Use jquery as the JavaScript library
gem 'pg' # Use PostgreSQL as the database for Active Record
gem 'puma', '~> 3.0' # Use Puma as the app server
-gem 'rails', '~> 5.0.0', '>= 5.0.0.1' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
+gem 'rails', '~> 5.0.1' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
+gem 'rb-readline' # Why is this suddenly such a problem?
gem 'sass-rails', '~> 5.0' # Use SCSS for stylesheets
-gem 'turbolinks', '~> 5' # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'uglifier', '>= 1.3.0' # Use Uglifier as compressor for JavaScript assets
+# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
+# gem 'turbolinks', '~> 5'
+
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
-
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
@@ -24,12 +29,24 @@ gem 'uglifier', '>= 1.3.0' # Use Uglifier as compressor for JavaScript assets
# gem 'capistrano-rails', group: :development
group :development, :test do
+ gem "brakeman", require: false # code analysis (http://brakemanscanner.org)
gem 'byebug', platform: :mri # Call 'byebug' anywhere in the code to stop execution and get a debugger console
- gem 'rspec-rails', '~> 3.5'
+ gem 'capybara' # allow interaction with DOM in tests
+ gem 'chromedriver-helper'
+ # gem 'chunky_png' # read png images
+ gem 'jasmine-rails' # JavaScript testing
+ gem 'jshint'
+ gem 'launchy'
+ gem 'poltergeist'
+ gem 'rspec-rails', '~> 3.5' # Use RSpec for tests
+ gem 'rubocop' # Enforce ruby code style
+ gem 'selenium-webdriver'
+ gem 'simplecov', require: false # determine code coverage of tests
+ gem 'teaspoon-jasmine'
end
group :development do
- gem 'better_errors'
+ gem 'better_errors' # show a much more friendly error page with a command line REPL
gem 'binding_of_caller' # used by better_errors to provide a REPL in the error window
gem 'listen', '~> 3.0.5'
gem 'spring' # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
diff --git a/Gemfile.lock b/Gemfile.lock
index 1d36497c..2bf38bc8 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,52 +1,71 @@
GEM
remote: https://rubygems.org/
specs:
- actioncable (5.0.0.1)
- actionpack (= 5.0.0.1)
+ actioncable (5.0.1)
+ actionpack (= 5.0.1)
nio4r (~> 1.2)
websocket-driver (~> 0.6.1)
- actionmailer (5.0.0.1)
- actionpack (= 5.0.0.1)
- actionview (= 5.0.0.1)
- activejob (= 5.0.0.1)
+ actionmailer (5.0.1)
+ actionpack (= 5.0.1)
+ actionview (= 5.0.1)
+ activejob (= 5.0.1)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
- actionpack (5.0.0.1)
- actionview (= 5.0.0.1)
- activesupport (= 5.0.0.1)
+ actionpack (5.0.1)
+ actionview (= 5.0.1)
+ activesupport (= 5.0.1)
rack (~> 2.0)
rack-test (~> 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
- actionview (5.0.0.1)
- activesupport (= 5.0.0.1)
+ actionview (5.0.1)
+ activesupport (= 5.0.1)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
- activejob (5.0.0.1)
- activesupport (= 5.0.0.1)
+ activejob (5.0.1)
+ activesupport (= 5.0.1)
globalid (>= 0.3.6)
- activemodel (5.0.0.1)
- activesupport (= 5.0.0.1)
- activerecord (5.0.0.1)
- activemodel (= 5.0.0.1)
- activesupport (= 5.0.0.1)
+ activemodel (5.0.1)
+ activesupport (= 5.0.1)
+ activerecord (5.0.1)
+ activemodel (= 5.0.1)
+ activesupport (= 5.0.1)
arel (~> 7.0)
- activesupport (5.0.0.1)
+ activesupport (5.0.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7)
minitest (~> 5.1)
tzinfo (~> 1.1)
- arel (7.1.2)
+ addressable (2.5.0)
+ public_suffix (~> 2.0, >= 2.0.2)
+ archive-zip (0.7.0)
+ io-like (~> 0.3.0)
+ arel (7.1.4)
+ ast (2.3.0)
better_errors (2.1.1)
coderay (>= 1.0.0)
erubis (>= 2.6.6)
rack (>= 0.9.0)
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
- builder (3.2.2)
+ brakeman (3.5.0)
+ builder (3.2.3)
byebug (9.0.6)
+ capybara (2.11.0)
+ addressable
+ mime-types (>= 1.16)
+ nokogiri (>= 1.3.3)
+ rack (>= 1.0.0)
+ rack-test (>= 0.5.4)
+ xpath (~> 2.0)
+ childprocess (0.5.9)
+ ffi (~> 1.0, >= 1.0.11)
+ chromedriver-helper (1.0.0)
+ archive-zip (~> 0.7.0)
+ nokogiri (~> 1.6)
+ cliver (0.3.2)
coderay (1.1.1)
coffee-rails (4.2.1)
coffee-script (>= 2.2.0)
@@ -54,23 +73,52 @@ GEM
coffee-script (2.4.1)
coffee-script-source
execjs
- coffee-script-source (1.10.0)
- concurrent-ruby (1.0.2)
+ coffee-script-source (1.12.2)
+ concurrent-ruby (1.0.4)
debug_inspector (0.0.2)
- diff-lcs (1.2.5)
+ diff-lcs (1.3)
+ docile (1.1.5)
+ dotenv (2.1.2)
+ dotenv-rails (2.1.2)
+ dotenv (= 2.1.2)
+ railties (>= 3.2, < 5.1)
erubis (2.7.0)
+ excon (0.54.0)
+ excon-rails (1.0.0)
+ activesupport (>= 3.0)
+ excon (>= 0.18.0)
+ sweet_notifications (~> 1.0)
execjs (2.7.0)
- ffi (1.9.14)
+ ffi (1.9.17)
+ font-awesome-rails (4.7.0.1)
+ railties (>= 3.2, < 5.1)
globalid (0.3.7)
activesupport (>= 4.1.0)
i18n (0.7.0)
- jbuilder (2.6.0)
+ i18n-js (3.0.0.rc15)
+ i18n (~> 0.6, >= 0.6.6)
+ io-like (0.3.0)
+ jasmine-core (2.5.2)
+ jasmine-rails (0.14.1)
+ jasmine-core (>= 1.3, < 3.0)
+ phantomjs (>= 1.9)
+ railties (>= 3.2.0)
+ sprockets-rails
+ jbuilder (2.6.1)
activesupport (>= 3.0.0, < 5.1)
multi_json (~> 1.2)
- jquery-rails (4.2.1)
+ jquery-rails (4.2.2)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
+ jshint (1.5.0)
+ execjs (>= 1.4.0)
+ multi_json (~> 1.0)
+ therubyracer (~> 0.12.1)
+ json (2.0.3)
+ launchy (2.4.3)
+ addressable (~> 2.3)
+ libv8 (3.16.14.17)
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
@@ -83,45 +131,56 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mini_portile2 (2.1.0)
- minitest (5.9.1)
+ minitest (5.10.1)
multi_json (1.12.1)
nio4r (1.2.1)
- nokogiri (1.6.8)
+ nokogiri (1.7.0.1)
mini_portile2 (~> 2.1.0)
- pkg-config (~> 1.1.7)
+ parser (2.3.3.1)
+ ast (~> 2.2)
pg (0.19.0)
- pkg-config (1.1.7)
- puma (3.6.0)
+ phantomjs (2.1.1.0)
+ poltergeist (1.12.0)
+ capybara (~> 2.1)
+ cliver (~> 0.3.1)
+ websocket-driver (>= 0.2.0)
+ powerpack (0.1.1)
+ public_suffix (2.0.5)
+ puma (3.6.2)
rack (2.0.1)
rack-test (0.6.3)
rack (>= 1.0)
- rails (5.0.0.1)
- actioncable (= 5.0.0.1)
- actionmailer (= 5.0.0.1)
- actionpack (= 5.0.0.1)
- actionview (= 5.0.0.1)
- activejob (= 5.0.0.1)
- activemodel (= 5.0.0.1)
- activerecord (= 5.0.0.1)
- activesupport (= 5.0.0.1)
+ rails (5.0.1)
+ actioncable (= 5.0.1)
+ actionmailer (= 5.0.1)
+ actionpack (= 5.0.1)
+ actionview (= 5.0.1)
+ activejob (= 5.0.1)
+ activemodel (= 5.0.1)
+ activerecord (= 5.0.1)
+ activesupport (= 5.0.1)
bundler (>= 1.3.0, < 2.0)
- railties (= 5.0.0.1)
+ railties (= 5.0.1)
sprockets-rails (>= 2.0.0)
- rails-dom-testing (2.0.1)
+ rails-dom-testing (2.0.2)
activesupport (>= 4.2.0, < 6.0)
- nokogiri (~> 1.6.0)
+ nokogiri (~> 1.6)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
- railties (5.0.0.1)
- actionpack (= 5.0.0.1)
- activesupport (= 5.0.0.1)
+ railties (5.0.1)
+ actionpack (= 5.0.1)
+ activesupport (= 5.0.1)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
- rake (11.3.0)
- rb-fsevent (0.9.7)
+ rainbow (2.2.1)
+ rake (12.0.0)
+ rb-fsevent (0.9.8)
rb-inotify (0.9.7)
ffi (>= 0.5.0)
+ rb-readline (0.5.3)
+ ref (2.0.0)
+ request_store (1.3.2)
rspec-core (3.5.4)
rspec-support (~> 3.5.0)
rspec-expectations (3.5.0)
@@ -139,43 +198,72 @@ GEM
rspec-mocks (~> 3.5.0)
rspec-support (~> 3.5.0)
rspec-support (3.5.0)
- sass (3.4.22)
+ rubocop (0.47.1)
+ parser (>= 2.3.3.1, < 3.0)
+ powerpack (~> 0.1)
+ rainbow (>= 1.99.1, < 3.0)
+ ruby-progressbar (~> 1.7)
+ unicode-display_width (~> 1.0, >= 1.0.1)
+ ruby-progressbar (1.8.1)
+ rubyzip (1.2.0)
+ sass (3.4.23)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
+ selenium-webdriver (3.0.5)
+ childprocess (~> 0.5)
+ rubyzip (~> 1.0)
+ websocket (~> 1.0)
+ simplecov (0.12.0)
+ docile (~> 1.1.0)
+ json (>= 1.8, < 3)
+ simplecov-html (~> 0.10.0)
+ simplecov-html (0.10.0)
spring (2.0.0)
activesupport (>= 4.2)
spring-watcher-listen (2.0.1)
listen (>= 2.7, < 4.0)
spring (>= 1.2, < 3.0)
- sprockets (3.7.0)
+ sprockets (3.7.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.2.0)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
- thor (0.19.1)
+ sweet_notifications (1.0.0)
+ activesupport (>= 4.0, < 6)
+ railties (>= 4.0, < 6)
+ request_store (~> 1.0)
+ teaspoon (1.1.5)
+ railties (>= 3.2.5, < 6)
+ teaspoon-jasmine (2.3.4)
+ teaspoon (>= 1.0.0)
+ therubyracer (0.12.3)
+ libv8 (~> 3.16.14.15)
+ ref
+ thor (0.19.4)
thread_safe (0.3.5)
tilt (2.0.5)
- turbolinks (5.0.1)
- turbolinks-source (~> 5)
- turbolinks-source (5.0.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)
- uglifier (3.0.2)
+ uglifier (3.0.4)
execjs (>= 0.3.0, < 3)
- web-console (3.3.1)
+ unicode-display_width (1.1.3)
+ web-console (3.4.0)
actionview (>= 5.0)
activemodel (>= 5.0)
debug_inspector
railties (>= 5.0)
+ websocket (1.2.3)
websocket-driver (0.6.4)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
+ xpath (2.0.0)
+ nokogiri (~> 1.3)
PLATFORMS
ruby
@@ -183,21 +271,36 @@ PLATFORMS
DEPENDENCIES
better_errors
binding_of_caller
+ brakeman
byebug
+ capybara
+ chromedriver-helper
coffee-rails (~> 4.2)
+ dotenv-rails
+ excon-rails
+ font-awesome-rails (>= 4.7.0)
+ i18n-js (>= 3.0.0.rc15)
+ jasmine-rails
jbuilder (~> 2.5)
jquery-rails
+ jshint
+ launchy
listen (~> 3.0.5)
pg
+ poltergeist
puma (~> 3.0)
- rails (~> 5.0.0, >= 5.0.0.1)
+ rails (~> 5.0.1)
+ rb-readline
rspec-rails (~> 3.5)
+ rubocop
sass-rails (~> 5.0)
+ selenium-webdriver
+ simplecov
spring
spring-watcher-listen (~> 2.0.0)
- turbolinks (~> 5)
+ teaspoon-jasmine
uglifier (>= 1.3.0)
web-console
BUNDLED WITH
- 1.12.5
+ 1.13.6
diff --git a/app/assets/images/geolocation-marker.svg b/app/assets/images/geolocation-marker.svg
new file mode 100644
index 00000000..ba92af72
--- /dev/null
+++ b/app/assets/images/geolocation-marker.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/app/assets/images/hubzone-map-marker.svg b/app/assets/images/hubzone-map-marker.svg
new file mode 100644
index 00000000..af4b605e
--- /dev/null
+++ b/app/assets/images/hubzone-map-marker.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/app/assets/images/icons/57x57.png b/app/assets/images/icons/57x57.png
new file mode 100644
index 00000000..4dd59b9a
Binary files /dev/null and b/app/assets/images/icons/57x57.png differ
diff --git a/app/assets/images/sba-logo.png b/app/assets/images/sba-logo.png
new file mode 100644
index 00000000..7613a3b5
Binary files /dev/null and b/app/assets/images/sba-logo.png differ
diff --git a/app/assets/javascripts/HZ.js.erb b/app/assets/javascripts/HZ.js.erb
new file mode 100644
index 00000000..b330fd75
--- /dev/null
+++ b/app/assets/javascripts/HZ.js.erb
@@ -0,0 +1,28 @@
+//this is our base level hubzone app namespace
+/* exported HZApp */
+window.HZApp = {
+ Autocomplete: {},
+ config: {
+ wmsEnabled: ("<%= MAP_CONFIG[:geom_wms_settings][:wms_enabled] %>" === "true")
+ },
+ Constructors: {},
+ GA: {},
+ GeoLocation: {},
+ HZQuery: {},
+ Layers: {
+ LayerUtils: {},
+ LayerDefs: {}
+ },
+ Legend: {},
+ map: {},
+ MapUtils: {},
+ Markers: {},
+ Print: {},
+ Report: {},
+ SidebarUtils: {},
+ Styles: {},
+ WMSUtils: {}
+};
+
+
+
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index c5c65d51..1897c863 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -12,6 +12,6 @@
//
//= require jquery
//= require jquery_ujs
-//= require turbolinks
//= require uswds
-//= require_tree .
+//= require HZ
+//= require i18n/translations
diff --git a/app/assets/javascripts/hzmap.js b/app/assets/javascripts/hzmap.js
new file mode 100644
index 00000000..b92f6382
--- /dev/null
+++ b/app/assets/javascripts/hzmap.js
@@ -0,0 +1,13 @@
+// This is a manifest file that'll be compiled into hzmap.js, which will include all the files
+// listed below.
+//
+// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
+//
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// compiled file. JavaScript code in this file should be added after the last require_* statement.
+//
+// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
+// about supported directives.
+//
+//= require_tree ./hzmap
diff --git a/app/assets/javascripts/hzmap/autocomplete.js b/app/assets/javascripts/hzmap/autocomplete.js
new file mode 100644
index 00000000..48340889
--- /dev/null
+++ b/app/assets/javascripts/hzmap/autocomplete.js
@@ -0,0 +1,21 @@
+// autocomplete contrustructor
+HZApp.Autocomplete = {
+ searchInput: function(){
+ return document.getElementById('search-field-small');
+ },
+ options: {
+ types: []
+ },
+ autocomplete: {},
+ createAutocomplete: function(){
+ this.autocomplete = new google.maps.places.Autocomplete(this.searchInput(), this.options);
+ },
+ createListener: function(autocompleteObject){
+ autocompleteObject.addListener('place_changed', this.triggerSearch($('.usa-search')) );
+ },
+ triggerSearch: function($selector) {
+ return function() {
+ $selector.submit();
+ };
+ }
+};
diff --git a/app/assets/javascripts/hzmap/ga.js b/app/assets/javascripts/hzmap/ga.js
new file mode 100644
index 00000000..d77020a0
--- /dev/null
+++ b/app/assets/javascripts/hzmap/ga.js
@@ -0,0 +1,39 @@
+/* exported GAs */
+HZApp.GA = (function() {
+
+ window.console = window.console || { };
+ if ( window.console.log === null ) {
+ window.console.log = function() { };
+ }
+
+ return {
+ navigateToPage: function(url){
+ return (document.location = url);
+ },
+ openLink : function( url, category, action, label, value ) {
+ // console.log( "GA.openLink: ", url, category, action, label, value );
+ if ( typeof ga === "function" ) {
+ var timeout = setTimeout( function() { HZApp.GA.navigateToPage(url); }, 500 );
+ ga( 'send', 'event', category || "outbound", action || "click", label || url, value, {
+ hitCallback : function() {
+ clearTimeout( timeout );
+ HZApp.GA.navigateToPage(url);
+ }
+ });
+ } else {
+ HZApp.GA.navigateToPage(url);
+ }
+ },
+ track : function( category, action, label, value ) {
+ //console.log( "GA.track: ", category, action, label, value );
+ if ( typeof ga === "function" ) {
+ ga( "send", "event", category, action, label, value );
+ }
+ },
+ trackSubmit : function(action, inputId) {
+ var term = $(inputId).val();
+ this.track( 'map', action, term );
+ }
+ };
+})();
+
diff --git a/app/assets/javascripts/hzmap/geolocation.js b/app/assets/javascripts/hzmap/geolocation.js
new file mode 100644
index 00000000..2c767258
--- /dev/null
+++ b/app/assets/javascripts/hzmap/geolocation.js
@@ -0,0 +1,45 @@
+/* exported GeoLocation */
+HZApp.GeoLocation = (function() {
+ // GeoLocation button listener
+ $(function() {
+ $('#geolocation').click(HZApp.GeoLocation.catchGeoLocationButtonClick);
+ });
+
+ return {
+ catchGeoLocationButtonClick: function(){
+ HZApp.GeoLocation.getUserLocation(window.navigator.geolocation);
+ },
+ getUserLocation: function(navLocation){
+ //grab users location and set map around it
+ $('#geolocation i').css("display", "none");
+ $('.geolocation-loading').css("display", "block");
+ if (navLocation) {
+ navLocation.getCurrentPosition(this.moveMapToUserLocation, this.geolocationError);
+ return navLocation;
+ } else {
+ //browser doesn't support Geolocation
+ $('#geolocation i').css("display", "block");
+ $('.geolocation-loading').css("display", "none");
+ // window.console.warn('browser does not support geolocation');
+ return null;
+ }
+ },
+ geolocationError: function() {
+ $('#geolocation i').css("display", "block");
+ $('.geolocation-loading').css("display", "none");
+ // window.console.log("unable to retrieve user location");
+ },
+ moveMapToUserLocation: function(position){
+ var pos = {
+ lat: position.coords.latitude,
+ lng: position.coords.longitude
+ };
+ //set map to that location
+ HZApp.map.setCenter(pos);
+ HZApp.map.setZoom(15);
+ HZApp.Markers.hzUserLocation.updateMarkers(pos);
+ $('#geolocation i').css("display", "block");
+ $('.geolocation-loading').css("display", "none");
+ }
+ };
+})();
diff --git a/app/assets/javascripts/hzmap/hz-query.js b/app/assets/javascripts/hzmap/hz-query.js
new file mode 100644
index 00000000..c1f78769
--- /dev/null
+++ b/app/assets/javascripts/hzmap/hz-query.js
@@ -0,0 +1,61 @@
+// utils for handling queries
+HZApp.HZQuery = {
+ query:{
+ latlng: null,
+ q: null,
+ zoom: null,
+ },
+ response: {},
+ parseResponse: function(response) {
+ //set the response for later
+ this.response = response;
+ this.response.geocodeLocation = null;
+ this.query.latlng = null;
+ this.query.q = null;
+
+ // handle bad responses
+ this.handleBadResponses(response.status);
+
+ // get all the desired geometry and attributes out of the response
+ this.parseResponseGeometry(this.response);
+
+ //finally, update the map with the new response
+ this.updateMap();
+ },
+ handleBadResponses: function(responseStatus){
+ if (responseStatus === 'ZERO_RESULTS' || responseStatus === 'INVALID_REQUEST'){
+ $('.sidebar-card.map-report').hide();
+ $('#sidebar-content').addClass('zero-results');
+ $('#legend').addClass('zero-results');
+ } else {
+ $('.sidebar-card.map-report').show();
+ $('#sidebar-content').removeClass('zero-results');
+ $('#legend').removeClass('zero-results');
+ }
+ },
+ parseResponseGeometry: function(response){
+ if (HZApp.HZQuery.response.geometry){
+ HZApp.MapUtils.jumpToLocation({
+ viewport: response.geometry.viewport,
+ location: response.geometry.location
+ });
+
+ this.response.geocodeLocation = response.geometry.location;
+
+ if (response.place_id){
+ this.query.q = response.formatted_address;
+ this.query.latlng = null;
+ } else {
+ this.query.q = null;
+ this.query.latlng = [response.geocodeLocation.lat, response.geocodeLocation.lng ].join(',');
+ }
+ }
+ },
+ updateMap: function(){
+ HZApp.SidebarUtils.sidebar.open();
+ HZApp.Markers.hzQueryMarker.updateMarkers(this.response.geocodeLocation);
+ },
+ resetStreetView: function (elem){
+ elem.click();
+ }
+};
diff --git a/app/assets/javascripts/hzmap/layer-defs.js b/app/assets/javascripts/hzmap/layer-defs.js
new file mode 100644
index 00000000..c853e62b
--- /dev/null
+++ b/app/assets/javascripts/hzmap/layer-defs.js
@@ -0,0 +1,43 @@
+// hubzone data layer style definitions
+
+// this object holds the current google overlays in the .overlay array
+// the layerIndex prop is used for order
+// the object that is stuck into overlay will have a setOpacity which is used for toggling
+
+HZApp.Layers.LayerDefs = (function(){
+
+ return {
+ hzWMSOverlays: {
+ indian_lands: {
+ layerIndex: 0,
+ layerGroup: 'indian_lands',
+ isVisible: true,
+ overlay: [],
+ },
+ qnmc_e: {
+ layerIndex: 1,
+ layerGroup: 'qnmc',
+ isVisible: true,
+ overlay:[],
+ },
+ redesignated_lg: {
+ layerIndex: 2,
+ layerGroup: 'redesignated',
+ isVisible: true,
+ overlay:[],
+ },
+ brac_lg: {
+ layerIndex: 3,
+ layerGroup: 'brac',
+ isVisible: true,
+ overlay:[],
+ },
+ qct_e: {
+ layerIndex: 4,
+ layerGroup: 'qct',
+ isVisible: true,
+ overlay:[],
+ }
+ }
+ };
+})();
diff --git a/app/assets/javascripts/hzmap/legend-defs.js b/app/assets/javascripts/hzmap/legend-defs.js
new file mode 100644
index 00000000..d8fb4a70
--- /dev/null
+++ b/app/assets/javascripts/hzmap/legend-defs.js
@@ -0,0 +1,134 @@
+// hubzone data layer style definitions
+
+// this object holds the current google overlays in the .overlay array and the per layer styles
+// order in this object defines draw order on the map:
+// first object is drawn first, then next on top of that, etc.
+HZApp.Legend.LegendDefs = (function(){
+ var legendDefaults = {
+ circleFillColor: '#FFFFFF',
+ circleFillOpacity: 0.5,
+ circleStrokeColor: '#CCCCCC',
+ circleStrokeOpacity: 1,
+ circleStrokeWidth: 1,
+ displacementX: 0,
+ displacementY: 0,
+ fillColor: '#CCCCCC',
+ fillOpacity: 0.5,
+ graphicSpacing: 10,
+ lineStrokeColor: '#fff',
+ lineStrokeOpacity: 1,
+ lineStrokeWidth: 1,
+ lineRotation: 0,
+ strokeColor: '#CCCCCC',
+ strokeOpacity: 1,
+ strokeWidth: 1.25,
+ tileSize: 10,
+
+ // // USWDS Alt 1
+ // qctColor: '#2E8540',
+ // qnmcColor: '#0071BB',
+ // indianLandsColor: '#4C2C92'
+
+ // Tyler 1
+ qctColor: '#0D465C',
+ qnmcColor: '#BA233F',
+ indianLandsColor: '#009DCD'
+ };
+
+ var legendKeys = {
+ qct: {
+ title: "Census Tract",
+ svg: [],
+ canToggle: true,
+ layerGroup: 'qct',
+ styleOptions: [
+ {
+ type: 'polygon',
+ fillColor: legendDefaults.qctColor,
+ fillOpacity: legendDefaults.fillOpacity,
+ strokeColor: legendDefaults.qctColor,
+ strokeOpacity: legendDefaults.strokeOpacity,
+ strokeWidth: legendDefaults.strokeWidth
+ }
+ ]
+ },
+ qnmc: {
+ title: "County",
+ svg: [],
+ canToggle: true,
+ layerGroup: 'qnmc',
+ styleOptions: [
+ {
+ type: 'polygon',
+ fillColor: legendDefaults.qnmcColor,
+ fillOpacity: legendDefaults.fillOpacity,
+ strokeColor: legendDefaults.qnmcColors,
+ strokeOpacity: legendDefaults.strokeOpacity,
+ strokeWidth: legendDefaults.strokeWidth
+ }
+ ]
+ },
+ indian_lands: {
+ title: "Indian Land",
+ svg: [],
+ canToggle: true,
+ layerGroup: 'indian_lands',
+ styleOptions: [
+ {
+ type: 'polygon',
+ fillColor: legendDefaults.indianLandsColor,
+ fillOpacity: legendDefaults.fillOpacity,
+ strokeColor: legendDefaults.indianLandsColor,
+ strokeOpacity: legendDefaults.strokeOpacity,
+ strokeWidth: legendDefaults.strokeWidth
+ }
+ ]
+ },
+ redesignated: {
+ title: "Redesignated",
+ svg: [],
+ canToggle: true,
+ layerGroup: 'redesignated',
+ styleOptions: [
+ {
+ type: 'horline',
+ lineStrokeColor: legendDefaults.lineStrokeColor,
+ lineStrokeWidth: 5,
+ lineStrokeOpacity: legendDefaults.fillOpacity,
+ strokeWidth: legendDefaults.strokeWidth,
+ strokeColor: legendDefaults.lineStrokeColor,
+ strokeOpacity: legendDefaults.strokeOpacity,
+ tileSize: 30,
+ lineRotation: 0
+ }
+ ]
+ },
+ brac: {
+ title: "Base Closure Area",
+ svg: [],
+ canToggle: true,
+ layerGroup: 'brac',
+ styleOptions: [
+ {
+ type: 'circle',
+ circleFillColor: '#fff',
+ circleFillOpacity: legendDefaults.fillOpacity,
+ circleStrokeColor: '#fff',
+ circleStrokeOpacity: legendDefaults.strokeOpacity,
+ circleStrokeWidth: legendDefaults.strokeWidth,
+ strokeColor: '#000000',
+ strokeOpacity: legendDefaults.strokeOpacity,
+ strokeWidth: legendDefaults.strokeWidth,
+ tileSize: 15,
+ graphicSpacing: legendDefaults.graphicSpacing
+ }
+ ]
+ },
+ };
+
+ return {
+ legendDefaults: legendDefaults,
+ legend: legendKeys
+ };
+
+})();
diff --git a/app/assets/javascripts/hzmap/legend.js.erb b/app/assets/javascripts/hzmap/legend.js.erb
new file mode 100644
index 00000000..49ca049f
--- /dev/null
+++ b/app/assets/javascripts/hzmap/legend.js.erb
@@ -0,0 +1,171 @@
+// legend utilties
+HZApp.Legend = (function(){
+ return {
+ legend: HZApp.Legend.LegendDefs.legend,
+ buildLegend: function(layers){
+ Object.keys(layers).map(function(layer){
+ var legendConfig = HZApp.Legend.getConfigFromLayerStyle(layers[layer]);
+ HZApp.Legend.legend[legendConfig.layerGroup].svg.push(HZApp.Legend.svgFromStyle(legendConfig));
+ });
+
+ Object.keys(this.legend).map(HZApp.Legend.insertLegendItem);
+
+ this.addLegendButtonListeners();
+
+ this.setLegendState(window.innerWidth);
+
+ this.addLayerToggleListeners();
+
+ },
+ addLegendButtonListeners: function(){
+ $('#legend-header').click(function(event) {
+ HZApp.Legend.toggleLegendVisibility(event.currentTarget.className);
+ });
+ },
+ toggleLegendVisibility: function(legendState) {
+ if(legendState === 'open') {
+ HZApp.Legend.hideLegend();
+ $('#legend-header').removeClass('open');
+ } else {
+ HZApp.Legend.showLegend();
+ $('#legend-header').addClass('open');
+ }
+ },
+ getConfigFromLayerStyle: function(layer){
+ return {
+ layerGroup: layer.layerGroup,
+ styleType: layer.styleOptions[0].type,
+ styleColor: layer.styleOptions[0][HZApp.Legend.legendTypeToColorType[layer.styleOptions[0].type]]
+ };
+ },
+ svgFromStyle: function(style){
+ var width = 34, height = 29;
+ var svg = this.svgHeader(width, height);
+ svg += '
hubzone legend';
+ var svg_fn_name = "svg_" + style.styleType;
+ svg += HZApp.Legend[svg_fn_name](style,width, height);
+ svg += '';
+ return svg;
+ },
+ svgHeader: function(width, height){
+ return ('