Try looking for a plugin:
https://woocommerce.com/product-category/woocommerce-extensions/shipping-methods/delivery-shipping-options/
If that doesn't work, you can code it:
You need to flag some products as 'local delivery only', but not others. That way at checkout time you can display the appropriate shipping options. You'll also need to know the user's Zip code etc.
Step 1: Add the flag to the product.
Create a check box on the product that allows you to flag it's a local ship item.
The code below will add the option in Products -> Product data -> Advanced
add_action('woocommerce_product_options_advanced', 'localship_options');
function localship_options()
{
echo '<div class="options_group">';
woocommerce_wp_checkbox(array(
'id' => 'localship',
'value' => get_post_meta(get_the_ID(), 'localship', true),
'label' => 'Local Ship',
'desc_tip' => true,
'description' => 'Only ships locally',
));
echo '</div>';
}
add_action('woocommerce_process_product_meta', 'localship_save_fields', 10, 2);
function localship_save_fields($id, $post)
{
if (!empty($_POST['localship'])) {
update_post_meta($id, 'localship', $_POST['localship']);
} else {
delete_post_meta($id, 'localship');
}
}
To see if a product is flagged or not, use get_post_meta. You'll need the id of the
product
$is_localship = get_post_meta( /*product id here */, 'localship', true);
Now you can use $is_localship to see if the product is a ship local.
Step 2: Check the Buyer's Zip Code
You'll need to get the user's order information.
The wc_get_order function should do it:
$order = wc_get_order( $order_id )
From there you should be able to pull out the user's address, zip code etc.
See if the buyer's zip code is in an array of local Zip codes.
Step 3: Display or Hide Shipping Accordingly
Now that you know if the product is local ship only and the Zip code is a match, you can show or hide the shipping option in your template.
You can use the $is_localship to display or hide the shipping box in your template.
That should get you going in the right direction.