Created
October 17, 2013 22:11
-
-
Save jakecraige/7033176 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * @file | |
| * leaflet powered custom maps for townelake homes. | |
| * by Jake Craige @ Poetic Systems | |
| */ | |
| /** | |
| * How To Import Lots | |
| * TL:DR Delete all current lots(feed/json), import feed lots, import json lots | |
| * ============================== | |
| * ***THIS MUST BE DONE IN ORDER*** | |
| * Go to /import and delete all current lots | |
| * Go to /lot-search and delete all non-feed based lots | |
| * Update JSON url in this file if necessary to current feed | |
| * Go to /import and import all lots | |
| * Go to /json and let that run | |
| * You're done! It's that easy | |
| * See me with any questions -Jake | |
| */ | |
| // Green | |
| $home_style = array( | |
| 'weight' => 1, | |
| 'color' => '#008000' | |
| ); | |
| // Blue | |
| $lot_style = array( | |
| 'weight' => 1, | |
| 'color' => '#0878BA' | |
| ); | |
| // Red | |
| $not_available_style = array( | |
| 'weight' => 1, | |
| 'color' => '#ED2228' | |
| ); | |
| // Gray | |
| $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)); | |
| //define('JSON_URL', 'http://jakecraige.com/geojson/townelake/townelake-part1.geojson'); | |
| define('JSON_URL', 'http://jakecraige.com/geojson/townelake/townelake-part2.geojson'); | |
| // This path pulls in the feed from the hard coded data source | |
| function townelake_maps_menu() { | |
| $items['json'] = array( | |
| 'title' => 'Parse GeoJson Feed', | |
| 'page callback' => 'townelake_maps_import_lots', | |
| 'access arguments' => array('access content'), | |
| 'type' => MENU_CALLBACK, | |
| ); | |
| $items['quick-home-search'] = array( | |
| 'title' => 'Drag the map around and zoom in to see specific lots', | |
| 'page callback' => 'townelake_maps_page', | |
| 'access arguments' => array('access content'), | |
| 'type' => MENU_CALLBACK, | |
| ); | |
| //'page arguments' => array(1), | |
| return $items; | |
| } | |
| function townelake_maps_page() { | |
| $lot_nodes = townelake_maps_get_lot_nodes(); | |
| $points = townelake_maps_process_geofield_data($lot_nodes); | |
| //dsm(count($points). 'points'); | |
| if (!empty($points)) { | |
| $styles = module_invoke_all('leaflet_map_info'); | |
| $default_settings = $styles['OSM Mapnik']['settings']; | |
| $attr_google = 'Map data © <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?lyrs=m@237049708&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, '800px'); | |
| } | |
| else { | |
| return "No points found"; | |
| } | |
| } | |
| function townelake_maps_get_lot_nodes() { | |
| $results = db_query("SELECT nid | |
| FROM {node} | |
| WHERE type='lot' | |
| AND status='1'"); | |
| foreach ($results as $result) { | |
| $home_ids[] = $result->nid; | |
| } | |
| $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 townelake_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) { | |
| $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_home_reference = field_get_items('node', $node, 'field_home_reference'); | |
| $field_section_reference = field_get_items('node', $node, 'field_section_reference'); | |
| $field_builder_reference = field_get_items('node', $node, 'field_builder_reference'); | |
| //dsm($field_builder_reference); | |
| $available = $field_available[0]['value']; | |
| $section_reference = $field_section_reference[0]['target_id']; | |
| $section = node_load($section_reference); | |
| $section_name = $section->field_marketing_name['und'][0]['value']; | |
| $section_sold_out = $section->field_sold_out['und'][0]['value']; | |
| $section_info = '<h4>Nid: '.$node->nid.'</h4>'; | |
| $section_info .= '<h4>Title/ID: '.$node->title.'</h4>'; | |
| $section_info .= '<h3>Section: '.$node->field_section_id['und'][0]['value'].'</h3>'; | |
| $section_info .= '<h3>Block: '.$node->field_block_id['und'][0]['value'].'</h3>'; | |
| $section_info .= '<h3>Lot: '.$node->field_lot_id['und'][0]['value'].'</h3>'; | |
| //$section_info .= '<p class="section-info">' | |
| //. townelake_maps_get_section_name($section_reference) . '</p> | |
| //<input type="hidden" value="'.$node->nid.'"/>'; | |
| // Status References: Available is " Available, Completed, Start" | |
| // if it red out or invalid builder? | |
| // Make it RED | |
| // if it gray out? - | |
| // Make it GRAY | |
| // else if it's not in sold out section | |
| // if it's available | |
| // if it has a home reference | |
| // make it GREEN | |
| // else no home reference | |
| // make it BLUE | |
| // else if has builder reference and not available | |
| // make it RED | |
| // else no builder reference and not available | |
| // make it GRAY | |
| // else in sold out section | |
| // mark it RED | |
| if(townelake_maps_get_red_out($node->nid) || townelake_maps_invalid_builder($node->nid)) { | |
| $data['options'] = unserialize(NOT_AVAILABLE_STYLE); | |
| $data['popup'] .= $section_info; | |
| $data['popup'] .= 'This lot is <b>not available</b>.'; | |
| } | |
| elseif(townelake_maps_get_gray_out($node->nid)) { | |
| $data['options'] = unserialize(OTHER_BUILDER_STYLE); | |
| $data['popup'] .= $section_info; | |
| $data['popup'] .= 'This lot is <b>not available</b>.'; | |
| } | |
| elseif(!townelake_maps_get_sold_out($section_reference)) { | |
| if($available) { | |
| if($field_home_reference) { | |
| $home_node = node_load($field_home_reference[0]['target_id']); | |
| $nid = $home_node->nid; | |
| $street_address = $home_node->field_address['und'][0]['thoroughfare']; | |
| $city_state = $home_node->field_address['und'][0]['locality'] | |
| . ', ' . $home_node->field_address['und'][0]['administrative_area'] | |
| . ' ' . $home_node->field_address['und'][0]['postal_code']; | |
| $body = $home_node->field_description['und'][0]['value']; | |
| $price = $home_node->field_price['und'][0]['value']; | |
| $sqft = $home_node->field_square_feet['und'][0]['value']; | |
| $beds = $home_node->field_bedrooms['und'][0]['value']; | |
| $baths = $home_node->field_bathrooms['und'][0]['value']; | |
| $image = $home_node->field_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 { // Available but not referenced to a home | |
| $data['options'] = unserialize(LOT_STYLE); | |
| $data['popup'] .= $section_info; | |
| $builder_nid = $field_builder_reference[0]['target_id']; | |
| if($builder_nid) { | |
| $builder_link = drupal_get_path_alias('node/' .$builder_nid ); | |
| $builder_name = townelake_maps_get_builder_name($builder_nid); | |
| $data['popup'] .= "This lot is <b>available</b>. <a href='$builder_link'>Contact $builder_name</a> to inquire about it."; | |
| } | |
| else { | |
| $data['popup'] .= "This lot is <b>available</b>. <a href='/welcome'>Contact us</a> to inquire about it."; | |
| } | |
| } | |
| } elseif($field_builder_reference[0]['target_id']) { // Not available, has builder | |
| $data['options'] = unserialize(NOT_AVAILABLE_STYLE); | |
| $data['popup'] .= $section_info; | |
| $data['popup'] .= 'This lot is <b>not available</b>.'; | |
| } else { // Lot not Available, no builder and not available status | |
| $data['options'] = unserialize(OTHER_BUILDER_STYLE); | |
| $data['popup'] .= $section_info; | |
| $data['popup'] .= 'This lot is <b>not available</b>.'; | |
| } | |
| } | |
| else { // In a sold out section | |
| $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(), | |
| ); | |
| } | |
| // If CS scoa , coming soon lot | |
| $geodata[] = $data; | |
| } | |
| } | |
| return $geodata; | |
| } | |
| function townelake_maps_parse_geojson_feed() { | |
| $geophp = geophp_load(); | |
| if (!$geophp) return FALSE; | |
| $json = file_get_contents(JSON_URL); | |
| $feed = json_decode($json); | |
| $results = array(); | |
| foreach($feed->features as $feature) { | |
| $geometry = json_encode($feature->geometry); | |
| $results[] = array( | |
| 'properties' => townelake_maps_process_job($feature->properties), | |
| townelake_maps_process_geojson($geometry) | |
| ); | |
| } | |
| return $results; | |
| } | |
| // Converts the json to a wkt format | |
| function townelake_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; | |
| } | |
| // format for the json to have an id | |
| function townelake_maps_process_job($properties) { | |
| return $properties->Section . '-' . $properties->Block . '-' . $properties->Lot; | |
| } | |
| function townelake_maps_import_lots() { | |
| $geojson = townelake_maps_parse_geojson_feed(); | |
| $feed_home_data = townelake_maps_generate_home_data(); | |
| foreach($feed_home_data as $home) { | |
| foreach($geojson as $key => $geo) { | |
| if($home['home_unique_id'] == $geo['properties']) { | |
| $node = node_load($home['nid']); | |
| townelake_maps_set_map_data($node, $geo); | |
| node_save($node); | |
| unset($geojson[$key]); | |
| break; | |
| } | |
| } | |
| } | |
| // Loop through the data not matched with a current lot in the lot feed and | |
| // add it as a new node | |
| foreach($geojson as $geo) { | |
| $node = new stdClass(); | |
| $node->type = 'lot'; | |
| node_object_prepare($node); | |
| $node->title = 'NotBuilt-' . $geo['properties']; | |
| $node->language = LANGUAGE_NONE; | |
| $node->uid = 1; | |
| // Default to not being available | |
| $node->field_available['und'][0]['value'] = 0; | |
| $section_reference = townelake_maps_get_section_reference($geo['properties']); | |
| $node->field_section_reference['und'][0]['target_id'] = $section_reference; | |
| preg_match('/(\w+)-(\w+)-(\w+)/', $geo['properties'], $matches); | |
| $section = $matches[1]; | |
| $block = $matches[2]; | |
| $lot = $matches[3]; | |
| $node->field_section_id['und'][0]['value'] = $section; | |
| $node->field_block_id['und'][0]['value'] = $block; | |
| $node->field_lot_id['und'][0]['value'] = $lot; | |
| townelake_maps_set_map_data($node, $geo); | |
| node_submit($node); | |
| node_save($node); | |
| } | |
| echo 'Lot Import Done.'; | |
| } | |
| // Used to create identifier from section, block, and lot that is used | |
| // to compare the home with the lot data | |
| function townelake_maps_generate_home_data() { | |
| // Normal Feed | |
| $feeds = db_query("SELECT entity_id FROM {feeds_item} WHERE id='lot'"); | |
| $feeds_info = array(); | |
| foreach($feeds as $feed) { | |
| $node = node_load($feed->entity_id); | |
| $section = $node->field_section_id[$node->language][0]['value']; | |
| $block = $node->field_block_id[$node->language][0]['value']; | |
| $lot = $node->field_lot_id[$node->language][0]['value']; | |
| $id = $section . '-' . $block . '-' . $lot; | |
| $feeds_info[] = array('nid' => $feed->entity_id, | |
| 'home_unique_id' => $id); | |
| } | |
| // End Normal Feed | |
| // Manual Import | |
| //$feed_one = db_query("SELECT entity_id FROM {feeds_item} WHERE id='manual_lot_1'"); | |
| //$feed_two = db_query("SELECT entity_id FROM {feeds_item} WHERE id='manual_lot_2'"); | |
| //$feeds_info = array(); | |
| //foreach($feed_one as $feed) { | |
| //$node = node_load($feed->entity_id); | |
| //$section = $node->field_section_id[$node->language][0]['value']; | |
| //$block = $node->field_block_id[$node->language][0]['value']; | |
| //$lot = $node->field_lot_id[$node->language][0]['value']; | |
| //$id = $section . '-' . $block . '-' . $lot; | |
| //$feeds_info[] = array('nid' => $feed->entity_id, | |
| //'home_unique_id' => $id); | |
| //} | |
| //foreach($feed_two as $feed) { | |
| //$node = node_load($feed->entity_id); | |
| //$section = $node->field_section_id[$node->language][0]['value']; | |
| //$block = $node->field_block_id[$node->language][0]['value']; | |
| //$lot = $node->field_lot_id[$node->language][0]['value']; | |
| //$id = $section . '-' . $block . '-' . $lot; | |
| //$feeds_info[] = array('nid' => $feed->entity_id, | |
| //'home_unique_id' => $id); | |
| //} | |
| // End Manual Import | |
| return $feeds_info; | |
| } | |
| // Returns Entity ID for Section Reference when given the properties of the | |
| // geofield | |
| function townelake_maps_get_section_reference($properties) { | |
| // Pull section number out of calculated properties | |
| preg_match('/(\w+)/', $properties, $matches); | |
| $section_matches = db_query("SELECT entity_id | |
| FROM {field_data_field_section_number} | |
| WHERE field_section_number_value = :num | |
| LIMIT 1", | |
| array(':num' => $matches[0])); | |
| foreach($section_matches as $match) { | |
| return $match->entity_id; | |
| } | |
| return 0; | |
| } | |
| function townelake_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 townelake_maps_get_section_name($section_id) { | |
| $query = db_query("SELECT field_marketing_name_value | |
| FROM {field_data_field_marketing_name} | |
| WHERE entity_id=:nid | |
| LIMIT 1", | |
| array(':nid' => $section_id )); | |
| foreach($query as $q) { | |
| return $q->field_marketing_name_value; | |
| } | |
| } | |
| function townelake_maps_get_sold_out($section_id) { | |
| $query = db_query("SELECT field_sold_out_value | |
| FROM {field_data_field_sold_out} | |
| WHERE entity_id=:nid | |
| LIMIT 1", | |
| array(':nid' => $section_id )); | |
| foreach($query as $q) { | |
| return $q->field_sold_out_value; | |
| } | |
| } | |
| function townelake_maps_get_gray_out($nid) { | |
| $query = db_query("SELECT field_gray_out_value | |
| FROM {field_data_field_gray_out} | |
| WHERE entity_id=:nid | |
| LIMIT 1", | |
| array(':nid' => $nid )); | |
| foreach($query as $q) { | |
| return $q->field_gray_out_value; | |
| } | |
| } | |
| function townelake_maps_get_red_out($nid) { | |
| $query = db_query("SELECT field_red_out_value | |
| FROM {field_data_field_red_out} | |
| WHERE entity_id=:nid | |
| LIMIT 1", | |
| array(':nid' => $nid )); | |
| foreach($query as $q) { | |
| return $q->field_red_out_value; | |
| } | |
| } | |
| function townelake_maps_get_builder_name($nid) { | |
| $query = db_query("SELECT title | |
| FROM {node} | |
| WHERE nid=:nid | |
| LIMIT 1", | |
| array(':nid' => $nid )); | |
| foreach($query as $q) { | |
| return $q->title; | |
| } | |
| } | |
| function townelake_maps_invalid_builder($nid) { | |
| $query = db_query("SELECT field_builder_id_value | |
| FROM {field_data_field_builder_id} | |
| WHERE entity_id=:nid | |
| LIMIT 1", | |
| array(':nid' => $nid )); | |
| $value = ''; | |
| foreach($query as $q) { | |
| $value = $q->field_builder_id_value; | |
| } | |
| // Excludes certain builder id's that aren't allowed to be green | |
| if($value == '8e8e97fa-5219-de11-967c-0015c5ec09eb' || | |
| $value == '8cd47444-9130-dc11-9bcf-0015c5ec09eb') { | |
| return true; | |
| } | |
| else { | |
| return false; | |
| } | |
| } | |
| // Used for logging important info to console | |
| function townelake_maps_log($message) { | |
| echo '<script type="text/javascript">'; | |
| echo 'console.log("' . $message . '")'; | |
| echo '</script>'; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment