Relatively new to the ArcGIS platform and am having difficulty trying to add to a feature datalayer used to plot points on a map. I was able to create a Wordpress template to display a map and add, edit and delete feature points that represent custom post types in Wordpress. I wrote a plug-in to do that using the REST API but I am getting an error 400. I used the parameters to create the same request in postman and I get the same error so I don't think it is my plug-in code but something with accessing the API. The format of my post is
https://services6.arcgis.com/ZZRuFbElIjfqGwkv/arcgis/rest/services/wp_comreal_listings/FeatureServer...
The body in JSON would be something like
{
"features": [
{
"attributes": {
"property_address": "645 San Lorenzo Ave",
"property_name": "test",
"city": "Miami",
"state": "FL",
"zip": "33146",
"lat": 25.731574741741348,
"lon": -80.2659019000002
},
"geometry": {
"x": -80.2659019000002,
"y": 25.731574741741348
}
}
]
}
but my response is
{"error":{"code":400,"message":"","details":["Invalid parameters"]}}
My plug-in code is
<?php
/**
* Plugin Name: ArcGIS Update Feature Layer
* Plugin URI: https://mindshaft.com/
* Description: Updates ArcGIS feature layer when a property is saved or deleted.
* Version: 1.0.0
* Author: Mindshaft LLC
* Author URI: https://mindshaft.com/
* Text Domain: arcgis-update-feature-layer
* Domain Path: /languages
*/
// Function to update ArcGIS feature layer when a property is saved or deleted
function update_arcgis_feature_layer($post_id) {
// Check if this is a property post type
if (get_post_type($post_id) === 'listings') {
// Fetch property data
$property_title = get_the_title($post_id);
$FeatureImage = get_the_post_thumbnail_url( $post_id, 'medium' );
$property_address = get_post_meta($post_id, 'property_address', true);
$property_name = get_post_meta($post_id, 'property_name', true);
$property_type = get_post_meta($post_id, 'property_type', true);
$star_rating = get_post_meta($post_id, 'star_rating', true);
$energy_star = get_post_meta($post_id, 'energy_star', true);
$leed_certified = get_post_meta($post_id, 'leed_certified', true);
$building_class = get_post_meta($post_id, 'building_class', true);
$building_status = get_post_meta($post_id, 'building_status', true);
$rba = get_post_meta($post_id, 'rba', true);
$total_available_space_sf = get_post_meta($post_id, 'total_available_space_sf', true);
$rentsfyr = get_post_meta($post_id, 'rentsfyr', true);
$secondary_type = get_post_meta($post_id, 'secondary_type', true);
$market_name = get_post_meta($post_id, 'market_name', true);
$submarket_name = get_post_meta($post_id, 'submarket_name', true);
$leasing_company_name = get_post_meta($post_id, 'leasing_company_name', true);
$leasing_company_contact = get_post_meta($post_id, 'leasing_company_contact', true);
$submarket_cluster = get_post_meta($post_id, 'submarket_cluster', true);
$city = get_post_meta($post_id, 'city', true);
$state = get_post_meta($post_id, 'state', true);
$zip = get_post_meta($post_id, 'zip', true);
$county_name = get_post_meta($post_id, 'county_name', true);
$sale_company_name = get_post_meta($post_id, 'sale_company_name', true);
$sale_company_contact = get_post_meta($post_id, 'sale_company_contact', true);
$for_sale_price = get_post_meta($post_id, 'for_sale_price', true);
$for_sale_status = get_post_meta($post_id, 'for_sale_status', true);
$last_sale_date = get_post_meta($post_id, 'last_sale_date', true);
$last_sale_price = get_post_meta($post_id, 'last_sale_price', true);
$percent_leased = get_post_meta($post_id, 'percent_leased', true);
$year_built = get_post_meta($post_id, 'year_built', true);
$year_renovated = get_post_meta($post_id, 'year_renovated', true);
$typical_floor_size = get_post_meta($post_id, 'typical_floor_size', true);
$parking_ratio = get_post_meta($post_id, 'parking_ratio', true);
$tenancy = get_post_meta($post_id, 'tenancy', true);
$fema_map_date = get_post_meta($post_id, 'fema_map_date', true);
$fema_map_identifier = get_post_meta($post_id, 'fema_map_identifier', true);
$firm_id = get_post_meta($post_id, 'firm_id', true);
$firm_panel_number = get_post_meta($post_id, 'firm_panel_number', true);
$in_sfha = get_post_meta($post_id, 'in_sfha', true);
$floodplain_area = get_post_meta($post_id, 'floodplain_area', true);
$latitude = get_post_meta($post_id, 'lat', true);
$longitude = get_post_meta($post_id, 'lon', true);
// Log field values
error_log("Property Title: " . $property_title . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Feature Image URL: ' . $FeatureImage . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Property Address: ' . $property_address . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Property Name: ' . $property_name . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Property Type: ' . $property_type . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Star Rating: ' . $star_rating . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Energy Star: ' . $energy_star . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('LEED Certified: ' . $leed_certified . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Building Class: ' . $building_class . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Building Status: ' . $building_status . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('RBA: ' . $rba . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Total Available Space (SF): ' . $total_available_space_sf . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Rent (SF/YR): ' . $rentsfyr . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Secondary Type: ' . $secondary_type . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Market Name: ' . $market_name . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Submarket Name: ' . $submarket_name . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Leasing Company Name: ' . $leasing_company_name . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Leasing Company Contact: ' . $leasing_company_contact . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Submarket Cluster: ' . $submarket_cluster . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('City: ' . $city, 3, ABSPATH . 'wp-content/debug.log');
error_log('State: ' . $state, 3, ABSPATH . 'wp-content/debug.log');
error_log('ZIP: ' . $zip, 3, ABSPATH . 'wp-content/debug.log');
error_log('County Name: ' . $county_name . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Sale Company Name: ' . $sale_company_name . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Sale Company Contact: ' . $sale_company_contact . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('For Sale Price: ' . $for_sale_price . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('For Sale Status: ' . $for_sale_status . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Last Sale Date: ' . $last_sale_date . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Last Sale Price: ' . $last_sale_price . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Percent Leased: ' . $percent_leased . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Year Built: ' . $year_built . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Year Renovated: ' . $year_renovated . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Typical Floor Size: ' . $typical_floor_size . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Parking Ratio: ' . $parking_ratio . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Tenancy: ' . $tenancy . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('FEMA Map Date: ' . $fema_map_date . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('FEMA Map Identifier: ' . $fema_map_identifier . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Firm ID: ' . $firm_id . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Firm Panel Number: ' . $firm_panel_number . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('In SFHA: ' . $in_sfha . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Floodplain Area: ' . $floodplain_area . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Latitude: ' . $latitude . "\n", 3, ABSPATH . 'wp-content/debug.log');
error_log('Longitude: ' . $longitude . "\n", 3, ABSPATH . 'wp-content/debug.log');
// Format property data for ArcGIS
$arcgis_data = array(
'attributes' => array(
'PostID' => $post_id,
'FeatureImage' => $FeatureImage ?: null,
'property_address' => $property_address,
'property_name' => $property_name ?: null,
'property_type' => $property_type ?: null,
'star_rating' => $star_rating !== '' ? floatval($star_rating) : null,
'energy_star' => $energy_star ?: null,
'leed_certified' => $leed_certified ?: null,
'building_class' => $building_class ?: null,
'building_status' => $building_status ?: null,
'rba' => $rba !== '' ? floatval($rba) : null,
'total_available_space_sf' => $total_available_space_sf !== '' ? floatval($total_available_space_sf) : null,
'rentsfyr' => $rentsfyr !== '' ? floatval($rentsfyr) : null,
'secondary_type' => $secondary_type ?: null,
'market_name' => $market_name ?: null,
'submarket_name' => $submarket_name ?: null,
'leasing_company_name' => $leasing_company_name ?: null,
'leasing_company_contact' => $leasing_company_contact ?: null,
'submarket_cluster' => $submarket_cluster ?: null,
'city' => $city ?: null,
'state' => $state ?: null,
'zip' => $zip ?: null,
'county_name' => $county_name ?: null,
'sale_company_name' => $sale_company_name ?: null,
'sale_company_contact' => $sale_company_contact ?: null,
'for_sale_price' => $for_sale_price !== '' ? floatval($for_sale_price) : null,
'for_sale_status' => $for_sale_status ?: null,
'last_sale_date' => $last_sale_date ?: null,
'last_sale_price' => $last_sale_price !== '' ? floatval($last_sale_price) : null,
'percent_leased' => $percent_leased !== '' ? floatval($percent_leased) : null,
'year_built' => $year_built !== '' ? intval($year_built) : null,
'year_renovated' => $year_renovated !== '' ? intval($year_renovated) : null,
'typical_floor_size' => $typical_floor_size !== '' ? floatval($typical_floor_size) : null,
'parking_ratio' => $parking_ratio ?: null,
'tenancy' => $tenancy ?: null,
'fema_map_date' => $fema_map_date ?: null,
'fema_map_identifier' => $fema_map_identifier ?: null,
'firm_id' => $firm_id ?: null,
'firm_panel_number' => $firm_panel_number ?: null,
'in_sfha' => $in_sfha ?: null,
'floodplain_area' => $floodplain_area ?: null,
'lat' => $latitude !== '' ? floatval($latitude) : null,
'lon' => $longitude !== '' ? floatval($longitude) : null,
),
'geometry' => array(
'x' => $longitude !== '' ? floatval($longitude) : null,
'y' => $latitude !== '' ? floatval($latitude) : null,
)
);
// Log the ArcGIS data
error_log("\n\nArcGIS data: " . json_encode($arcgis_data) . "\n\n", 3, ABSPATH . 'wp-content/debug.log');
// Send data to ArcGIS REST API
$arcgis_api_key = 'MY-API-TOKEN';
$arcgis_url = 'MY-ARCGIS-SERVER-URL' . urlencode($arcgis_api_key);
$headers = array(
'Content-Type' => 'application/json',
);
$body = array(
'features' => array($arcgis_data)
);
// Log the request body
error_log('Request body: ' . json_encode($body) . "\n\n", 3, ABSPATH . 'wp-content/debug.log');
$response = wp_remote_post($arcgis_url, array(
'headers' => $headers,
'body' => json_encode($body),
));
// Log the API response
error_log('API response: ' . wp_remote_retrieve_body($response) . "\n\n", 3, ABSPATH . 'wp-content/debug.log');
// Check for errors
if (is_wp_error($response)) {
error_log('Error updating ArcGIS feature layer: ' . $response->get_error_message() . "\n\n", 3, ABSPATH . 'wp-content/debug.log');
} else {
$response_body = json_decode(wp_remote_retrieve_body($response), true);
if (isset($response_body['error'])) {
error_log('Error updating ArcGIS feature layer: ' . $response_body['error']['message'] . "\n\n", 3, ABSPATH . 'wp-content/debug.log');
} else {
error_log('Feature layer updated successfully' . "\n\n", 3, ABSPATH . 'wp-content/debug.log');
}
}
}
}
// Hook to update ArcGIS feature layer when a property is saved
add_action('acf/save_post', 'update_arcgis_feature_layer', 20);
// Hook to update ArcGIS feature layer when a property is deleted
add_action('delete_post', 'update_arcgis_feature_layer');
?>
Would love some help understanding what I'm doing wrong
Instead of building your array as one big overall statement, try building it in segments - print_r() is your friend as you walk through the process. Don't forget your token -
// Format property data for ArcGIS $arcgis_data = array( 'attributes' => array(
Try doing this ---
$dataElements = [ Put your Attribute Elements here ];
Then do the next portion of the array
$attributeData = ['attributes' => Data Elements];
Finally, be sure you have all the control fields (right of ?) where you have previously built them and the URL with the Token string.
$postData .= $fields . "&features" . json_encode($attributeDat);
And be sure to set your content length in the CUROPT_HTTPHEADER.
Thanks, but I dont think it has anything to do with the size of the array. I tried several options with less fields as in the first code block above and continue to get the same error. In fact I tried with just the geometry and address and still get the error. I get the same error no matter if I try submitting through postman, curl or direct API. I think perhaps it might be a permissions issue or something un-related to my code?
It's not the size of the array it's the construct you need to place an array inside an array and json_encode as you go. Try this and you will see the difference -
<?php
$arcgis_data = array(
'attributes' => array(
'PostID' => $post_id,
'FeatureImage' => $FeatureImage ?: null,
'property_address' => $property_address,
'property_name' => $property_name ?: null,
'property_type' => $property_type ?: null,
'star_rating' => $star_rating !== '' ? floatval($star_rating) : null,
'energy_star' => $energy_star ?: null,
'leed_certified' => $leed_certified ?: null,
'building_class' => $building_class ?: null,
'building_status' => $building_status ?: null,
'rba' => $rba !== '' ? floatval($rba) : null,
'total_available_space_sf' => $total_available_space_sf !== '' ? floatval($total_available_space_sf) : null,
'rentsfyr' => $rentsfyr !== '' ? floatval($rentsfyr) : null,
'secondary_type' => $secondary_type ?: null,
'market_name' => $market_name ?: null,
'submarket_name' => $submarket_name ?: null,
'leasing_company_name' => $leasing_company_name ?: null,
'leasing_company_contact' => $leasing_company_contact ?: null,
'submarket_cluster' => $submarket_cluster ?: null,
'city' => $city ?: null,
'state' => $state ?: null,
'zip' => $zip ?: null,
'county_name' => $county_name ?: null,
'sale_company_name' => $sale_company_name ?: null,
'sale_company_contact' => $sale_company_contact ?: null,
'for_sale_price' => $for_sale_price !== '' ? floatval($for_sale_price) : null,
'for_sale_status' => $for_sale_status ?: null,
'last_sale_date' => $last_sale_date ?: null,
'last_sale_price' => $last_sale_price !== '' ? floatval($last_sale_price) : null,
'percent_leased' => $percent_leased !== '' ? floatval($percent_leased) : null,
'year_built' => $year_built !== '' ? intval($year_built) : null,
'year_renovated' => $year_renovated !== '' ? intval($year_renovated) : null,
'typical_floor_size' => $typical_floor_size !== '' ? floatval($typical_floor_size) : null,
'parking_ratio' => $parking_ratio ?: null,
'tenancy' => $tenancy ?: null,
'fema_map_date' => $fema_map_date ?: null,
'fema_map_identifier' => $fema_map_identifier ?: null,
'firm_id' => $firm_id ?: null,
'firm_panel_number' => $firm_panel_number ?: null,
'in_sfha' => $in_sfha ?: null,
'floodplain_area' => $floodplain_area ?: null,
'lat' => $latitude !== '' ? floatval($latitude) : null,
'lon' => $longitude !== '' ? floatval($longitude) : null,
),
'geometry' => array(
'x' => $longitude !== '' ? floatval($longitude) : null,
'y' => $latitude !== '' ? floatval($latitude) : null,
)
);
printf("Your Data Arrays \n");
print_r($arcgis_data);
printf("\n");
$dataElements = array (
'PostID' => $post_id,
'FeatureImage' => $FeatureImage ?: null,
'property_address' => $property_address,
'property_name' => $property_name ?: null,
'property_type' => $property_type ?: null,
'star_rating' => $star_rating !== '' ? floatval($star_rating) : null,
'energy_star' => $energy_star ?: null,
'leed_certified' => $leed_certified ?: null,
'building_class' => $building_class ?: null,
'building_status' => $building_status ?: null,
'rba' => $rba !== '' ? floatval($rba) : null,
'total_available_space_sf' => $total_available_space_sf !== '' ? floatval($total_available_space_sf) : null,
'rentsfyr' => $rentsfyr !== '' ? floatval($rentsfyr) : null,
'secondary_type' => $secondary_type ?: null,
'market_name' => $market_name ?: null,
'submarket_name' => $submarket_name ?: null,
'leasing_company_name' => $leasing_company_name ?: null,
'leasing_company_contact' => $leasing_company_contact ?: null,
'submarket_cluster' => $submarket_cluster ?: null,
'city' => $city ?: null,
'state' => $state ?: null,
'zip' => $zip ?: null,
'county_name' => $county_name ?: null,
'sale_company_name' => $sale_company_name ?: null,
'sale_company_contact' => $sale_company_contact ?: null,
'for_sale_price' => $for_sale_price !== '' ? floatval($for_sale_price) : null,
'for_sale_status' => $for_sale_status ?: null,
'last_sale_date' => $last_sale_date ?: null,
'last_sale_price' => $last_sale_price !== '' ? floatval($last_sale_price) : null,
'percent_leased' => $percent_leased !== '' ? floatval($percent_leased) : null,
'year_built' => $year_built !== '' ? intval($year_built) : null,
'year_renovated' => $year_renovated !== '' ? intval($year_renovated) : null,
'typical_floor_size' => $typical_floor_size !== '' ? floatval($typical_floor_size) : null,
'parking_ratio' => $parking_ratio ?: null,
'tenancy' => $tenancy ?: null,
'fema_map_date' => $fema_map_date ?: null,
'fema_map_identifier' => $fema_map_identifier ?: null,
'firm_id' => $firm_id ?: null,
'firm_panel_number' => $firm_panel_number ?: null,
'in_sfha' => $in_sfha ?: null,
'floodplain_area' => $floodplain_area ?: null,
'lat' => $latitude !== '' ? floatval($latitude) : null,
'lon' => $longitude !== '' ? floatval($longitude) : null,
);
$geoElements = array(
'x' => $longitude !== '' ? floatval($longitude) : null,
'y' => $latitude !== '' ? floatval($latitude) : null
);
$attributeData = json_encode(array_merge(['attributes' => $dataElements],['goeometry' => $geoElements]));
printf("Individual Arrays \n");
print_r($dataElements);
print_r($geoElements);
printf("Combined Arrays \n");
print_r($attributeData);
printf("\n");
$bearerToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$fields = "token=" . $bearerToken;
$fields .= "&f=pjson&rollbackOnFailure=true";
$postData = $fields . "&features=" . json_encode($attributeData);
printf("\n");
printf("Post Data for CURL \n");
print_r($postData);
printf("\n");
?>