| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| using System; |
| using System.Collections.Generic; |
| using System.Text; |
| using Spatial4n.Core.Context; |
| using Spatial4n.Core.Io; |
| using Spatial4n.Core.Shapes; |
| |
| namespace Lucene.Net.Spatial.Queries |
| { |
| public class SpatialArgsParser |
| { |
| public const String DIST_ERR_PCT = "distErrPct"; |
| public const String DIST_ERR = "distErr"; |
| |
| /// <summary> |
| /// Writes a close approximation to the parsed input format. |
| /// </summary> |
| /// <param name="args"></param> |
| /// <returns></returns> |
| public static String WriteSpatialArgs(SpatialArgs args) |
| { |
| var str = new StringBuilder(); |
| str.Append(args.Operation.Name); |
| str.Append('('); |
| str.Append(args.Shape); |
| if (args.DistErrPct != null) |
| str.Append(" distErrPct=").Append(String.Format("{0:0.00}%", args.DistErrPct * 100d)); |
| if (args.DistErr != null) |
| str.Append(" distErr=").Append(args.DistErr); |
| str.Append(')'); |
| return str.ToString(); |
| } |
| |
| /// <summary> |
| /// Parses a string such as "Intersects(-10,20,-8,22) distErrPct=0.025". |
| /// </summary> |
| /// <param name="v"></param> |
| /// <param name="ctx"></param> |
| /// <returns></returns> |
| public SpatialArgs Parse(String v, SpatialContext ctx) |
| { |
| int idx = v.IndexOf('('); |
| int edx = v.LastIndexOf(')'); |
| |
| if (idx < 0 || idx > edx) |
| { |
| throw new ArgumentException("missing parens: " + v); |
| } |
| |
| SpatialOperation op = SpatialOperation.Get(v.Substring(0, idx).Trim()); |
| |
| //Substring in .NET is (startPosn, length), But in Java it's (startPosn, endPosn) |
| //see http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#substring(int, int) |
| String body = v.Substring(idx + 1, edx - (idx + 1)).Trim(); |
| if (body.Length < 1) |
| { |
| throw new ArgumentException("missing body : " + v); |
| } |
| |
| var shape = ctx.ReadShape(body); |
| var args = new SpatialArgs(op, shape); |
| |
| if (v.Length > (edx + 1)) |
| { |
| body = v.Substring(edx + 1).Trim(); |
| if (body.Length > 0) |
| { |
| Dictionary<String, String> aa = ParseMap(body); |
| args.DistErrPct = ReadDouble(aa["distErrPct"]); aa.Remove(DIST_ERR_PCT); |
| args.DistErr = ReadDouble(aa["distErr"]); aa.Remove(DIST_ERR); |
| if (aa.Count != 0) |
| { |
| throw new ArgumentException("unused parameters: " + aa); |
| } |
| } |
| } |
| args.Validate(); |
| return args; |
| } |
| |
| protected static double? ReadDouble(String v) |
| { |
| double val; |
| return double.TryParse(v, out val) ? val : (double?)null; |
| } |
| |
| protected static bool ReadBool(String v, bool defaultValue) |
| { |
| bool ret; |
| return bool.TryParse(v, out ret) ? ret : defaultValue; |
| } |
| |
| /// <summary> |
| /// Parses "a=b c=d f" (whitespace separated) into name-value pairs. If there |
| /// is no '=' as in 'f' above then it's short for f=f. |
| /// </summary> |
| /// <param name="body"></param> |
| /// <returns></returns> |
| protected static Dictionary<String, String> ParseMap(String body) |
| { |
| var map = new Dictionary<String, String>(); |
| int tokenPos = 0; |
| var st = body.Split(new[] { ' ', '\n', '\t' }, StringSplitOptions.RemoveEmptyEntries); |
| while (tokenPos < st.Length) |
| { |
| String a = st[tokenPos++]; |
| int idx = a.IndexOf('='); |
| if (idx > 0) |
| { |
| String k = a.Substring(0, idx); |
| String v = a.Substring(idx + 1); |
| map[k] = v; |
| } |
| else |
| { |
| map[a] = a; |
| } |
| } |
| return map; |
| } |
| |
| } |
| } |