Site Suitability Tool

Siting of affordable housing at different densities is a widely acknowledged need across Edgartown, Oak Bluffs, Tisbury and West Tisbury. To help address this, the Martha’s Vineyard Commission contracted with Bluegear Labs with a grant from the State’s Office of Energy and Environmental Affairs to develop a Site Suitability Tool for housing.

There are numerous datasets embedded in the tool whose weights can be customized by user preference. These preferences will impact scores assigned to parcels across a given town, once an analysis is generated. Scores will reflect preliminary site suitability for various densities of housing development. The aim here is to provide you a practical way to integrate your town knowledge so that site scores truly reflect local interests.

The mapping interface component will afford you, as the user, the ability to cross reference site locations and their respective scores paired within a larger neighborhood context, while assessing the distribution or concentration of these sites. We hope this tool can serve as a resource for periodic reference as well as enable quantitative comparison of sites across towns and between individual sites – with analysis that accounts for regulatory and community forces that shape local development decisions.

Instructions

Please be aware that this application is in beta and still actively being developed. One of the known issues is the extended loading time. After selecting a town from the dropdown, we recommend using the filters to limit the number of results in order to speed up the calculations and performance.

  1. You can view informational map layers or the map legend using the buttons in the right column.
  2. To begin using the tool, select a town from the drop-down menu.
  3. While the data is loading, you will seeing a Loading icon at the top of the screen. Once the data is fully loaded and the map updated, the icon will disappear.
  4. If there is an error while loading the data, you will see an alert icon and message. You can dismiss the alert and try again. If the error persists, we recommend refreshing the page.
  5. You can click on a parcel on the map to view basic information about the parcel.
  6. To limit the number of results, use the filters to find a parcel by address, Map & Lot ID, or minimum number of bedrooms.
  7. You can adjust the scoring factors by dragging the slider for each of the factors. Dragging a slider to the left will minimize the factor's impact on the parcel's total score.
  8. Currently, the factors available for scoring are:
    • Zoning Density (points allocated for the parcel's zoning regulation).
    • Pts / Bedroom (points allocated per bedroom as of right)
    • Vacant Lot (points allocated for a vacant lot as determined by a building value of less than $25,000)
    • Assessed Value (points allocated for the parcel's assessed value).
    • Historic District (wether or not the parcel is within the town's Historic District)
    • Overlay Zoning (whether or not the parcel overlaps a potentially restrictive zone such as DCPC or water resource protection)
    • Watershed Condition
    • NHESP Priority Habitat
    • Wetlands
    • Sewered parcels
    • Town Water parcels
    • Proximity to public bus routes
    • Proximity to Business District
    • Proximity to Shared Use Paths
  9. After you have adjusted the scoring factors, click the Calculate button to run the calculations and update the parcels' scores.
  10. To view all details for a parcel, click the button in the results row.
  11. To reset the filters and view all parcels for the selected town, click the "Reset Filters" button above the results.
  12. To select parcels for comparison, scroll down to the Results table and click on the checkbox next to the parcels you'd like to compare. When you have finished selecting parcels, click the "View Selected Parcels" button that appears next to the map in the right sidebar.
  13. To export the data as a .xls worksheet, click on either the "Download All Results" or "Download Filtered Results" and you will be prompted to download the file. You may see a warning about the format of the file and the file extension not matching when you open the file - click "Yes" and then click "Ok" when prompted about opening the Web Page as an Excel document.

Get Started

Whoops! There was an error.
ErrorException (E_WARNING)
file_put_contents(): Only 0 of 222 bytes written, possibly out of free disk space ErrorException thrown with message "file_put_contents(): Only 0 of 222 bytes written, possibly out of free disk space" Stacktrace: #7 ErrorException in /var/www/site_suitability/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:122 #6 file_put_contents in /var/www/site_suitability/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:122 #5 Illuminate\Filesystem\Filesystem:put in /var/www/site_suitability/vendor/laravel/framework/src/Illuminate/Session/FileSessionHandler.php:83 #4 Illuminate\Session\FileSessionHandler:write in /var/www/site_suitability/vendor/laravel/framework/src/Illuminate/Session/Store.php:129 #3 Illuminate\Session\Store:save in /var/www/site_suitability/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php:87 #2 Illuminate\Session\Middleware\StartSession:terminate in /var/www/site_suitability/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:218 #1 Illuminate\Foundation\Http\Kernel:terminateMiddleware in /var/www/site_suitability/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:189 #0 Illuminate\Foundation\Http\Kernel:terminate in /var/www/site_suitability/public/index.php:60
7
ErrorException
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Filesystem
/
Filesystem.php
122
6
file_put_contents
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Filesystem
/
Filesystem.php
122
5
Illuminate
\
Filesystem
\
Filesystem
put
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Session
/
FileSessionHandler.php
83
4
Illuminate
\
Session
\
FileSessionHandler
write
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Session
/
Store.php
129
3
Illuminate
\
Session
\
Store
save
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Session
/
Middleware
/
StartSession.php
87
2
Illuminate
\
Session
\
Middleware
\
StartSession
terminate
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Foundation
/
Http
/
Kernel.php
218
1
Illuminate
\
Foundation
\
Http
\
Kernel
terminateMiddleware
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Foundation
/
Http
/
Kernel.php
189
0
Illuminate
\
Foundation
\
Http
\
Kernel
terminate
/
public
/
index.php
60
/
var
/
www
/
site_suitability
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Filesystem
/
Filesystem.php
     *
     * @param  string  $path
     * @return string
     */
    public function hash($path)
    {
        return md5_file($path);
    }
 
    /**
     * Write the contents of a file.
     *
     * @param  string  $path
     * @param  string  $contents
     * @param  bool  $lock
     * @return int
     */
    public function put($path, $contents, $lock = false)
    {
        return file_put_contents($path, $contents, $lock ? LOCK_EX : 0);
    }
 
    /**
     * Prepend to a file.
     *
     * @param  string  $path
     * @param  string  $data
     * @return int
     */
    public function prepend($path, $data)
    {
        if ($this->exists($path)) {
            return $this->put($path, $data.$this->get($path));
        }
 
        return $this->put($path, $data);
    }
 
    /**
     * Append to a file.
Arguments
  1. "file_put_contents(): Only 0 of 222 bytes written, possibly out of free disk space"
    
/
var
/
www
/
site_suitability
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Filesystem
/
Filesystem.php
     *
     * @param  string  $path
     * @return string
     */
    public function hash($path)
    {
        return md5_file($path);
    }
 
    /**
     * Write the contents of a file.
     *
     * @param  string  $path
     * @param  string  $contents
     * @param  bool  $lock
     * @return int
     */
    public function put($path, $contents, $lock = false)
    {
        return file_put_contents($path, $contents, $lock ? LOCK_EX : 0);
    }
 
    /**
     * Prepend to a file.
     *
     * @param  string  $path
     * @param  string  $data
     * @return int
     */
    public function prepend($path, $data)
    {
        if ($this->exists($path)) {
            return $this->put($path, $data.$this->get($path));
        }
 
        return $this->put($path, $data);
    }
 
    /**
     * Append to a file.
Arguments
  1. "/var/www/site_suitability/storage/framework/sessions/MPJK54Yyejiwuus7Or1qbi9QzZCkkdK5EAbzKXRk"
    
  2. "a:4:{s:6:"_token";s:40:"cHolApbhlAHgwoW7WFFb8pWyB3oEoP9GUbQCNYDf";s:9:"_previous";a:1:{s:3:"url";s:28:"http://138.197.105.123/intro";}s:22:"PHPDEBUGBAR_STACK_DATA";a:0:{}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}"
    
  3. 2
    
/
var
/
www
/
site_suitability
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Session
/
FileSessionHandler.php
    /**
     * {@inheritdoc}
     */
    public function read($sessionId)
    {
        if ($this->files->isFile($path = $this->path.'/'.$sessionId)) {
            if ($this->files->lastModified($path) >= Carbon::now()->subMinutes($this->minutes)->getTimestamp()) {
                return $this->files->sharedGet($path);
            }
        }
 
        return '';
    }
 
    /**
     * {@inheritdoc}
     */
    public function write($sessionId, $data)
    {
        $this->files->put($this->path.'/'.$sessionId, $data, true);
 
        return true;
    }
 
    /**
     * {@inheritdoc}
     */
    public function destroy($sessionId)
    {
        $this->files->delete($this->path.'/'.$sessionId);
 
        return true;
    }
 
    /**
     * {@inheritdoc}
     */
    public function gc($lifetime)
    {
        $files = Finder::create()
Arguments
  1. "/var/www/site_suitability/storage/framework/sessions/MPJK54Yyejiwuus7Or1qbi9QzZCkkdK5EAbzKXRk"
    
  2. "a:4:{s:6:"_token";s:40:"cHolApbhlAHgwoW7WFFb8pWyB3oEoP9GUbQCNYDf";s:9:"_previous";a:1:{s:3:"url";s:28:"http://138.197.105.123/intro";}s:22:"PHPDEBUGBAR_STACK_DATA";a:0:{}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}"
    
  3. true
    
/
var
/
www
/
site_suitability
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Session
/
Store.php
     *
     * @param  string  $data
     * @return string
     */
    protected function prepareForUnserialize($data)
    {
        return $data;
    }
 
    /**
     * Save the session data to storage.
     *
     * @return bool
     */
    public function save()
    {
        $this->ageFlashData();
 
        $this->handler->write($this->getId(), $this->prepareForStorage(
            serialize($this->attributes)
        ));
 
        $this->started = false;
    }
 
    /**
     * Prepare the serialized session data for storage.
     *
     * @param  string  $data
     * @return string
     */
    protected function prepareForStorage($data)
    {
        return $data;
    }
 
    /**
     * Age the flash data for the session.
     *
     * @return void
Arguments
  1. "MPJK54Yyejiwuus7Or1qbi9QzZCkkdK5EAbzKXRk"
    
  2. "a:4:{s:6:"_token";s:40:"cHolApbhlAHgwoW7WFFb8pWyB3oEoP9GUbQCNYDf";s:9:"_previous";a:1:{s:3:"url";s:28:"http://138.197.105.123/intro";}s:22:"PHPDEBUGBAR_STACK_DATA";a:0:{}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}"
    
/
var
/
www
/
site_suitability
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Session
/
Middleware
/
StartSession.php
        if ($this->sessionConfigured()) {
            $this->storeCurrentUrl($request, $session);
 
            $this->addCookieToResponse($response, $session);
        }
 
        return $response;
    }
 
    /**
     * Perform any final actions for the request lifecycle.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Symfony\Component\HttpFoundation\Response  $response
     * @return void
     */
    public function terminate($request, $response)
    {
        if ($this->sessionHandled && $this->sessionConfigured() && ! $this->usingCookieSessions()) {
            $this->manager->driver()->save();
        }
    }
 
    /**
     * Start the session for the given request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Contracts\Session\Session
     */
    protected function startSession(Request $request)
    {
        return tap($this->getSession($request), function ($session) use ($request) {
            $session->setRequestOnHandler($request);
 
            $session->start();
        });
    }
 
    /**
     * Get the session implementation from the manager.
/
var
/
www
/
site_suitability
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Foundation
/
Http
/
Kernel.php
     * @return void
     */
    protected function terminateMiddleware($request, $response)
    {
        $middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(
            $this->gatherRouteMiddleware($request),
            $this->middleware
        );
 
        foreach ($middlewares as $middleware) {
            if (! is_string($middleware)) {
                continue;
            }
 
            list($name) = $this->parseMiddleware($middleware);
 
            $instance = $this->app->make($name);
 
            if (method_exists($instance, 'terminate')) {
                $instance->terminate($request, $response);
            }
        }
    }
 
    /**
     * Gather the route middleware for the given request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function gatherRouteMiddleware($request)
    {
        if ($route = $request->route()) {
            return $this->router->gatherRouteMiddleware($route);
        }
 
        return [];
    }
 
    /**
Arguments
  1. Request {#42
      #json: null
      #convertedFiles: null
      #userResolver: Closure {#291
        class: "Illuminate\Auth\AuthServiceProvider"
        this: AuthServiceProvider {#32 …}
        parameters: {
          $guard: {
            default: null
          }
        }
        use: {
          $app: Application {#2 …}
        }
      }
      #routeResolver: Closure {#298
        class: "Illuminate\Routing\Router"
        this: Router {#25 …}
        use: {
          $route: Route {#158 …}
        }
      }
      +attributes: ParameterBag {#44}
      +request: ParameterBag {#50}
      +query: ParameterBag {#50}
      +server: ServerBag {#46}
      +files: FileBag {#47}
      +cookies: ParameterBag {#45}
      +headers: HeaderBag {#48}
      #content: null
      #languages: null
      #charsets: null
      #encodings: null
      #acceptableContentTypes: array:1 [
        0 => "*/*"
      ]
      #pathInfo: "/intro"
      #requestUri: "/intro"
      #baseUrl: ""
      #basePath: null
      #method: "GET"
      #format: null
      #session: Store {#342}
      #locale: null
      #defaultLocale: "en"
      -isHostValid: true
      -isForwardedValid: true
      basePath: ""
      format: "html"
    }
    
  2. Response {#357}
    
/
var
/
www
/
site_suitability
/
vendor
/
laravel
/
framework
/
src
/
Illuminate
/
Foundation
/
Http
/
Kernel.php
     */
    protected function dispatchToRouter()
    {
        return function ($request) {
            $this->app->instance('request', $request);
 
            return $this->router->dispatch($request);
        };
    }
 
    /**
     * Call the terminate method on any terminable middleware.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Http\Response  $response
     * @return void
     */
    public function terminate($request, $response)
    {
        $this->terminateMiddleware($request, $response);
 
        $this->app->terminate();
    }
 
    /**
     * Call the terminate method on any terminable middleware.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Http\Response  $response
     * @return void
     */
    protected function terminateMiddleware($request, $response)
    {
        $middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(
            $this->gatherRouteMiddleware($request),
            $this->middleware
        );
 
        foreach ($middlewares as $middleware) {
            if (! is_string($middleware)) {
Arguments
  1. Request {#42
      #json: null
      #convertedFiles: null
      #userResolver: Closure {#291
        class: "Illuminate\Auth\AuthServiceProvider"
        this: AuthServiceProvider {#32 …}
        parameters: {
          $guard: {
            default: null
          }
        }
        use: {
          $app: Application {#2 …}
        }
      }
      #routeResolver: Closure {#298
        class: "Illuminate\Routing\Router"
        this: Router {#25 …}
        use: {
          $route: Route {#158 …}
        }
      }
      +attributes: ParameterBag {#44}
      +request: ParameterBag {#50}
      +query: ParameterBag {#50}
      +server: ServerBag {#46}
      +files: FileBag {#47}
      +cookies: ParameterBag {#45}
      +headers: HeaderBag {#48}
      #content: null
      #languages: null
      #charsets: null
      #encodings: null
      #acceptableContentTypes: array:1 [
        0 => "*/*"
      ]
      #pathInfo: "/intro"
      #requestUri: "/intro"
      #baseUrl: ""
      #basePath: null
      #method: "GET"
      #format: null
      #session: Store {#342}
      #locale: null
      #defaultLocale: "en"
      -isHostValid: true
      -isForwardedValid: true
      basePath: ""
      format: "html"
    }
    
  2. Response {#357}
    
/
var
/
www
/
site_suitability
/
public
/
index.php
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
 
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
 
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
 
$response->send();
 
$kernel->terminate($request, $response);
 
Arguments
  1. Request {#42
      #json: null
      #convertedFiles: null
      #userResolver: Closure {#291
        class: "Illuminate\Auth\AuthServiceProvider"
        this: AuthServiceProvider {#32 …}
        parameters: {
          $guard: {
            default: null
          }
        }
        use: {
          $app: Application {#2 …}
        }
      }
      #routeResolver: Closure {#298
        class: "Illuminate\Routing\Router"
        this: Router {#25 …}
        use: {
          $route: Route {#158 …}
        }
      }
      +attributes: ParameterBag {#44}
      +request: ParameterBag {#50}
      +query: ParameterBag {#50}
      +server: ServerBag {#46}
      +files: FileBag {#47}
      +cookies: ParameterBag {#45}
      +headers: HeaderBag {#48}
      #content: null
      #languages: null
      #charsets: null
      #encodings: null
      #acceptableContentTypes: array:1 [
        0 => "*/*"
      ]
      #pathInfo: "/intro"
      #requestUri: "/intro"
      #baseUrl: ""
      #basePath: null
      #method: "GET"
      #format: null
      #session: Store {#342}
      #locale: null
      #defaultLocale: "en"
      -isHostValid: true
      -isForwardedValid: true
      basePath: ""
      format: "html"
    }
    
  2. Response {#357}
    

Environment & details:

empty
empty
empty
empty
empty
Key Value
REDIRECT_STATUS
"200"
HTTP_ACCEPT
"*/*"
HTTP_USER_AGENT
"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)"
HTTP_ACCEPT_ENCODING
"gzip, br, zstd, deflate"
HTTP_HOST
"138.197.105.123"
HTTP_VIA
"1.1 squid-proxy-5b5d847c96-b6z2f (squid/6.10)"
HTTP_X_FORWARDED_FOR
"10.1.181.64"
HTTP_CACHE_CONTROL
"max-age=259200"
HTTP_CONNECTION
"keep-alive"
PATH
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
SERVER_SIGNATURE
"<address>Apache/2.4.29 (Ubuntu) Server at 138.197.105.123 Port 80</address>\n"
SERVER_SOFTWARE
"Apache/2.4.29 (Ubuntu)"
SERVER_NAME
"138.197.105.123"
SERVER_ADDR
"138.197.105.123"
SERVER_PORT
"80"
REMOTE_ADDR
"216.73.216.177"
DOCUMENT_ROOT
"/var/www/site_suitability/public"
REQUEST_SCHEME
"http"
CONTEXT_PREFIX
""
CONTEXT_DOCUMENT_ROOT
"/var/www/site_suitability/public"
SERVER_ADMIN
"webmaster@localhost"
SCRIPT_FILENAME
"/var/www/site_suitability/public/index.php"
REMOTE_PORT
"24348"
REDIRECT_URL
"/intro"
GATEWAY_INTERFACE
"CGI/1.1"
SERVER_PROTOCOL
"HTTP/1.1"
REQUEST_METHOD
"GET"
QUERY_STRING
""
REQUEST_URI
"/intro"
SCRIPT_NAME
"/index.php"
PHP_SELF
"/index.php"
REQUEST_TIME_FLOAT
1752505407.473
REQUEST_TIME
1752505407
empty
0. Whoops\Handler\PrettyPageHandler