         (errors/throw-service-error :bad-request (format "Cannot transform source CRS [%s] to WGS 84" src-crs-name))))
     geometry))
 
+(defn feature-point-count
+  "Get the number of points in the Feature"
+  [feature]
+  (let [crs (when (.getDefaultGeometryProperty feature)
+              (-> feature .getDefaultGeometryProperty .getDescriptor .getCoordinateReferenceSystem))
+        properties (.getProperties feature)
+        geometry-props (filter (fn [p] (geo/geometry? (.getValue p))) properties)
+        geometries (map #(-> % .getValue (transform-to-epsg-4326 crs)) geometry-props)]
+    (apply + (map geometry-point-count geometries))))
+
+(defn features-point-count
+  "Compute the number of points in a list of Features"
+  [features]
+  (reduce (fn [total feature] (+ total (feature-point-count feature)))
+          0
+          features))
+
+(defn validate-point-count
+  "Validate that the number of points in the features is greater than zero and less than the limit"
+  [features]
+  (let [point-count (features-point-count features)]
+    (if (= point-count 0)
+      "Shapefile has no points"
+      (when (> point-count (max-shapefile-points))
+        (format "Number of points in shapefile exceeds the limit of %d"
+          (max-shapefile-points))))))
+
+(defn- validate-feature-count
+  "Validates that the number of features is greater than zero and less than the limit"
+  [features]
+  (let [feature-count (count features)]
+    (if (= feature-count 0)
+      "Shapefile has no features"
+      (when (> feature-count (max-shapefile-features))
+        (format "Shapefile feature count [%d] exceeds the %d feature limit"
+          feature-count
+          (max-shapefile-features))))))
+
+(defn validate-features
+  "Validate this list of features in terms of shapefile limits"
+  [features]
+  (when-let [message (or (validate-feature-count features) (validate-point-count features))]
+    (errors/throw-service-error :bad-request message)))
+
 (defn feature->conditions
   "Process the contents of a Feature to return query conditions along with number of points in
   the processed Feature. The `context` map can be used to pass along additional info."

  "The maximum number of points a shapefile can have"
  {:default 5000 :type Long})

(defn unzip-file
  "Unzip a file (of type File) into a temporary directory and return the directory path as a File"
  [source]

          (throw e) ;; This was a more specific service error so just re-throw it
          (errors/throw-service-error :bad-request "Failed to parse KML file"))))))

(defn in-memory->conditions-vec
  "Converts a group of features produced by simplification to a vector of SpatialConditions"
  [shapefile-info]
  (let [^ArrayList features (:tempfile shapefile-info)
        mime-type (:content-type shapefile-info)]
    (features->conditions features mime-type)))

(defmulti shapefile->conditions
  "Converts a shapefile to query conditions based on shapefile format"
