Skip to content

Instantly share code, notes, and snippets.

@jakecraige
Created February 17, 2014 16:57
Show Gist options
  • Save jakecraige/9054483 to your computer and use it in GitHub Desktop.
Save jakecraige/9054483 to your computer and use it in GitHub Desktop.
<?php
/**
* @file
* leaflet powered custom maps for newmark homes.
*/
$home_style = array(
'weight' => 1,
'color' => '#008000'
);
$lot_style = array(
'weight' => 1,
'color' => '#0878BA'
);
$not_available_style = array(
'weight' => 1,
'color' => '#ED2228'
);
$other_builder_style = array(
'weight' => 1,
'color' => '#B1B1B1'
);
define('HOME_STYLE', serialize($home_style));
define('LOT_STYLE', serialize($lot_style));
define('NOT_AVAILABLE_STYLE', serialize($not_available_style));
define('OTHER_BUILDER_STYLE', serialize($other_builder_style));
# prevents nodes from being created or updated when going to /json
# shows NID on map in popup
define('DEV_MODE', false);
//Erin - 713 346 0173
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/Riverstone_80.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/riverstone1.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/cross-creek-ranch-bend-70.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/cross-creek-ranch-creek-bend-section-9.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/cypress_creek_lakes_section_10.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/siennaplantation9.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/siennaplantation19.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/sienna-plantation-section-22.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/sienna-plantation-section-23.geojson');
//define('JSON_URL', 'http://newmarkhomes.com/sites/newmarkhomes.com/files/feeds/Section24.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/pinemill23.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/pinemill24.geojson');
//define('JSON_URL', 'http://jakecraige.com/geojson/newmark/pinemill25.geojson');
define('JSON_URL', 'http://jakecraige.com/geojson/newmark/pinemill26.geojson');
// This path pulls in the feed from the hard coded data source
function newmark_maps_menu() {
$items['json'] = array(
'title' => 'Parse GeoJson Feed',
'page callback' => 'newmark_maps_import_lots',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$items['lot-map-fullscreen'] = array(
'title' => 'Fullscreen Lot Map',
'page callback' => 'newmark_maps_page',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
//'page arguments' => array(1),
return $items;
}
function newmark_maps_page() {
// This is used to only return the map when we are on the community page
// eg. communities/riverstone and not communities/riverstone/home-address...
$arg_length = count(explode('/', request_path()));
if($arg_length == 2) {
$lot_nodes = newmark_maps_get_lot_nodes();
$points = newmark_maps_process_geofield_data($lot_nodes);
//leaflet_debug($points);
if (!empty($points)) {
$styles = module_invoke_all('leaflet_map_info');
$default_settings = $styles['OSM Mapnik']['settings'];
$attr_google = 'Map data &copy; <a href="http://googlemaps.com">Google</a>';
$prot = '//' ;
$map_info['google-high-res'] = array(
'label' => 'Google high-res road & terrain (zoom 0..18)',
'description' => t('Google road & terrain layers, with high-res (Retina) support'),
'settings' => array('layerControl' => TRUE) + $default_settings,
'layers' => array(
'terrain' => array(
'type' => 'google',
'urlTemplate' => $prot . 'mt{s}.googleapis.com/vt?lyrs=t,r&x={x}&y={y}&z={z}',
'options' => array(
'attribution' => $attr_google,
'detectRetina' => TRUE,
'subdomains' => array(0, 1, 2, 3)
)
),
'roadmap' => array(
'type' => 'google',
// For retina displays we append '&style=high_dpi&w=512',
// see leaflet_more_maps_preprocess_leaflet_map()
'urlTemplate' => $prot . 'mt{s}.googleapis.com/vt?x={x}&y={y}&z={z}',
'options' => array(
'attribution' => $attr_google,
'detectRetina' => TRUE,
'subdomains' => array(0, 1, 2, 3)
)
)
)
);
return leaflet_render_map($map_info['google-high-res'], $points, '500px');
}
return "";
}
}
function newmark_maps_get_lot_nodes() {
if((arg(0) == 'node' || arg(0) == 'lot-map-fullscreen') && is_numeric(arg(1))) {
$nodeid = arg(1);
}
$results = db_query('SELECT entity_id
FROM {field_data_field_community_entity}
WHERE field_community_entity_target_id = :nid',
array(':nid' => $nodeid));
foreach ($results as $result) {
$section_references[] = $result->entity_id;
}
// Sanity check to prevent sql error when going to communities/fakepath
if(count($section_references) > 0) {
$where = "WHERE field_section_reference_target_id = ";
$where .= implode(" OR field_section_reference_target_id = ", $section_references);
}
$results = db_query("SELECT n.entity_id
FROM {field_data_field_section_reference} n
$where");
foreach ($results as $result) {
$home_ids[] = $result->entity_id;
}
$homes = node_load_multiple($home_ids); // Array of Home Nodes
return $homes;
}
// TODO: Look into using leaflet_process_geofield function in leaflet.formatters.inc
function newmark_maps_process_geofield_data($nodes) {
geophp_load();
$geodata = array();
foreach ($nodes as $node) {
$field_geometry = field_get_items('node', $node, 'field_geometry');
if($field_geometry) {
$hasGeoCount += 1;
$field_geometry_wkt = $field_geometry[0]['wkt'];
$geometry = geoPHP::load($field_geometry_wkt, 'wkt');
$components = $geometry->getComponents();
$components = $components[0]->getComponents();
$data = array();
$data['type'] = 'polygon';
$data['leaflet_id'] = 'lot'.$node->nid;
$field_available = field_get_items('node', $node, 'field_available');
$field_other_builder = field_get_items('node', $node, 'field_other_builder');
$field_home_reference = field_get_items('node', $node, 'field_home_reference');
$field_section_reference = field_get_items('node', $node, 'field_section_reference');
$available = $field_available[0]['value'];
$other_builder = $field_other_builder[0]['value'];
$section_reference = $field_section_reference[0]['target_id'];
$section_info = '<p class="section-info">Section: '
. newmark_maps_get_section_name($section_reference)
. '</p>';
if(DEV_MODE) {
$section_info += '</p><h3>'.$node->nid.'</h3>';
}
if ($available) {
//if($field_home_reference) {
if(($field_home_reference[0]['target_id']) && ($home_node = node_load($field_home_reference[0]['target_id']))) {
$nid = $home_node->nid;
$street_address = $home_node->field_postal_address['und'][0]['thoroughfare'];
$city_state = $home_node->field_postal_address['und'][0]['locality']
. ', ' . $home_node->field_postal_address['und'][0]['administrative_area']
. ' ' . $home_node->field_postal_address['und'][0]['postal_code'];
$body = $home_node->body['und'][0]['value'];
$price = $home_node->field_price['und'][0]['value'];
$sqft = $home_node->field_computed_sqft['und'][0]['value'];
$beds = $home_node->field_computed_bed['und'][0]['value'];
$baths = $home_node->field_computed_bath['und'][0]['value'];
$image = $home_node->field_home_image['und'][0]['uri'];
$data['options'] = unserialize(HOME_STYLE);
$popup_html = '<h2><a href="/node/' . $nid . '">'
. $street_address . '<br>' . $city_state . '</a></h2>';
$popup_html .= $section_info;
$popup_html .= '<div class="left_fifty">';
$popup_html .= '<img width="100" height="80" src="' . drupal_realpath($image) . '">';
$popup_html .= '</div>';
$popup_html .= '<div class="right_fifty">';
$popup_html .= '<p>';
$popup_html .= '<span class="price">$' . number_format($price) . '</span><br>';
$popup_html .= '<span class="sqft">'
. number_format($sqft) . ' sqft</span><br>';
$popup_html .= "<span class=\"beds\">$beds beds</span><br>";
$popup_html .= '<span class="baths">'
. trim(trim($baths, 0), '.') . ' baths</span>';
$popup_html .= '</p>';
$popup_html .= '</div>';
$popup_html .= '<div class="body">';
if(strlen($body) > 160) {
$popup_html .= '<p>' . substr($body, 0 , 160) . '...</p>';
}
else {
$popup_html .= '<p>' . $body . '</p>';
}
$popup_html .= '</div>';
$data['popup'] .= $popup_html;
} else {
$data['options'] = unserialize(LOT_STYLE);
$data['popup'] .= $section_info;
$data['popup'] .= 'This lot is <b>available</b>. See the list of plans below.';
}
} else if($other_builder) {
$data['options'] = unserialize(OTHER_BUILDER_STYLE);
$data['popup'] .= $section_info;
//$data['popup'] = 'This lot is <b>not</b> owned by this builder</b>.';
} else {
$data['options'] = unserialize(NOT_AVAILABLE_STYLE);
$data['popup'] .= $section_info;
$data['popup'] .= 'This lot is <b>not available</b>.';
}
foreach ($components as $component) {
$data['points'][] = array(
'lat' => $component->getY(),
'lon' => $component->getX(),
);
}
$geodata[] = $data;
}
}
return $geodata;
}
function newmark_maps_parse_geojson_feed() {
$geophp = geophp_load();
if (!$geophp) return FALSE;
$json = file_get_contents(JSON_URL);
$feed = json_decode($json);
//print_r($feed);
$results = array();
foreach($feed->features as $feature) {
$geometry = json_encode($feature->geometry);
//print_r(newmark_maps_process_job($feature->properties));
$results[] = array(
//'properties' => newmark_maps_process_job($feature->properties),
'community' => $feature->properties->Community,
'section' => $feature->properties->Section,
'block' => newmark_maps_pad_zero($feature->properties->Block),
'lot' => newmark_maps_pad_zero($feature->properties->Lot),
newmark_maps_process_geojson($geometry)
);
}
return $results;
}
function newmark_maps_pad_zero($number) {
if (strlen($number) == 1) {
$number = '0' . $number;
}
return $number;
}
// Converts the json to a wkt format
function newmark_maps_process_geojson($geojson) {
$geom = geoPHP::load($geojson, 'json'); // DINGDING. DATA IS AN ARRAY, not json
$result = array('wkt' => $geom->out('wkt'));
geofield_compute_values($result, 'wkt'); // Uses reference to set value
return $result;
}
// This function appends 0s to properties that are a single digit to match the
// format for the job number
function newmark_maps_process_job($properties) {
foreach ($properties as $key => $property) {
if (strlen($property) == 1) {
$properties->$key = '0' . $property;
}
}
return $properties->Community . '-'
. $properties->Section . $properties->Block . $properties->Lot;
}
function newmark_maps_compare(&$node, &$geo) {
//echo $node->field_section_number['und'][0]['value'] . "==" . $geo['section'] . '<br>';
if(trim($node->field_lot_community_number['und'][0]['value']) == trim($geo['community']) &&
newmark_maps_pad_zero(trim($node->field_section_number['und'][0]['value'])) == newmark_maps_pad_zero(trim($geo['section'])) &&
newmark_maps_pad_zero(trim($node->field_block_number['und'][0]['value'])) == newmark_maps_pad_zero(trim($geo['block'])) &&
newmark_maps_pad_zero(trim($node->field_lot_number['und'][0]['value'])) == newmark_maps_pad_zero(trim($geo['lot']))
) {
return true;
} else {
return false;
}
}
function newmark_maps_import_lots() {
$feeds = db_query("SELECT entity_id FROM {feeds_item} WHERE id='lot_feed'");
$dirt_lots = db_query("SELECT entity_id FROM {feeds_item} WHERE id='dirt_lot_feed'");
$geojson = newmark_maps_parse_geojson_feed();
foreach($feeds as $feed) {
$node = node_load($feed->entity_id);
foreach($geojson as $key => $geo) {
if(newmark_maps_compare($node, $geo)) {
newmark_maps_set_map_data($node, $geo);
if(!DEV_MODE) {
node_save($node);
}
unset($geojson[$key]);
echo 'found match<br>';
}
}
}
foreach($dirt_lots as $feed) {
$node = node_load($feed->entity_id);
foreach($geojson as $key => $geo) {
if(newmark_maps_compare($node, $geo)) {
newmark_maps_set_map_data($node, $geo);
if(!DEV_MODE) {
node_save($node);
}
unset($geojson[$key]);
echo 'found match<br>';
}
}
}
// // Loop through the data not matched and add it as a new node
foreach($geojson as $geo) {
echo 'create node<br>';
$node = new stdClass();
$node->type = 'lot';
node_object_prepare($node);
$node->title = 'No-Match-L-' . $geo['community'] . "-" . $geo['section'] . $geo['block'] . $geo['lot'];
$node->language = LANGUAGE_NONE;
$node->uid = 1;
$node->field_available['und'][0]['value'] = 0;
$node->field_other_builder['und'][0]['value'] = 1;
$node->field_section_reference['und'][0]['target_id']
= newmark_maps_get_section_reference($geo['community']);
$node->field_section_number['und'][0]['value'] = $geo['section'];
$node->field_lot_community_number['und'][0]['value'] = $geo['community'];
$node->field_block_number['und'][0]['value'] = $geo['block'];
$node->field_lot_number['und'][0]['value'] = $geo['lot'];
newmark_maps_set_map_data($node, $geo);
if(!DEV_MODE) {
node_submit($node);
node_save($node);
}
}
}
// Returns Entity ID for Section Reference when given spec number
function newmark_maps_get_section_reference($section_number) {
$results = db_query("SELECT entity_id
FROM {feeds_item}
WHERE guid
LIKE '%$section_number%'
AND id='section_feed'
LIMIT 1");
foreach($results as $result) {
$entity_id = $result->entity_id;
}
return $entity_id;
}
function newmark_maps_set_map_data(&$node, &$geo) {
$node->field_geometry['und'][0]['wkt'] = $geo[0]['wkt'];
$node->field_geometry['und'][0]['geo_type'] = $geo[0]['geo_type'];
$node->field_geometry['und'][0]['lat'] = $geo[0]['lat'];
$node->field_geometry['und'][0]['lon'] = $geo[0]['lon'];
$node->field_geometry['und'][0]['top'] = $geo[0]['top'];
$node->field_geometry['und'][0]['bottom'] = $geo[0]['bottom'];
$node->field_geometry['und'][0]['right'] = $geo[0]['left'];
$node->field_geometry['und'][0]['left'] = $geo[0]['right'];
}
function newmark_maps_get_section_name($section_id) {
$query = db_query("SELECT title
FROM {node}
WHERE nid=:nid
LIMIT 1",
array(':nid' => $section_id ));
foreach($query as $q) {
return $q->title;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment